- Set의 특징 = 집합개념(중복 허용X) , 순서의미X
HashSet
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class T05HashSetTest {
public static void main(String[] args) {
Set hs1 = new HashSet();
// Set에 데이터를 추가할 때도 add()를 사용한다.
// 집합이라는 의미의 데이터를 관리할거라 순서의미도 X
hs1.add("DD");
hs1.add("AA");
hs1.add(2);
hs1.add("CC");
hs1.add("BB");
hs1.add(1);
hs1.add(3);
System.out.println("Set 데이터: " + hs1);
System.out.println();
// Set은 순서개념(인덱스를 통한 접근)이 없고, 데이터 중복을 허용하지 않는다.
// 그래서 이미 있는 데이터를 add하면 false를 반환하고, 데이터는 추가되지 않는다.
boolean isAdded = hs1.add("FF");
System.out.println("중복되지 않을 때: " + isAdded);
System.out.println("Set 데이터: " + hs1);
System.out.println();
isAdded = hs1.add("CC");
System.out.println("중복 될 때: " + isAdded);
System.out.println("Set 데이터: " + hs1);
System.out.println();
// Set의 데이터를 수정하려면 수정하는 메서드가 없기 때문에 해당 데이터를
// 삭제 후 새로운 데이터를 추가해 주어야 한다.
// 삭제하는 메서드
// 1) clear() => 모든 데이터 삭제
// 2) remove(삭제할 데이터) => 해당 데이터 삭제
// 예) 'FF'를 'EE'로 수정하기
hs1.remove("FF");
System.out.println("FF 데이터 삭제 후 데이터: " + hs1);
System.out.println();
hs1.add("EE");
System.out.println("EE 데이터 추가 후 데이터: " + hs1);
System.out.println();
hs1.clear();
System.out.println("Set의 데이터 개수: " + hs1.size());
// Set은 데이터의 인덱스 개념이 없기 때문에 List처럼 인덱스를 이용한 접근이 불가능하다.
// 그래서 데이터를 꺼내기 위해 Iterator객체를 사용한다.
Iterator it = hs1.iterator();
// hasNext() => 다음 위치에 데이터가 있는지 확인하고 있으면 true,
// 없으면 false를 반환한다.
while(it.hasNext()) {
// next() => 다음 위치의 데이터를 반환한다.
System.out.println(it.next());
}
// 1~100사이의 중복되지 않는 정수 5개 만들기
Set<Integer> intRnd = new HashSet<Integer>();
while(intRnd.size() < 5) {
int num = (int) (Math.random() * 100 + 1 );
intRnd.add(num);
}
System.out.println("만들어진 난수들 : " + intRnd);
// Collection 유형의 객체들은 서로 다른 자료 구조로 쉽게 변경해서 사용할 수 있다.
// 다른 종류의 객체를 생성할 때 변경할 데이터를 넣어주면 된다.
List<Integer> intRndList = new ArrayList<Integer>(intRnd);
System.out.println("List 데이터 출력...");
for (Integer i : intRndList) {
System.out.print(i + " ");
}
System.out.println();
}
}
- TreeSet
-
- headSet(E toElement): 세트에서 작은 요소부터 지정된 요소까지의 부분 세트를 반환합니다.
- tailSet(E fromElement): 세트에서 지정된 요소부터 큰 요소까지의 부분 세트를 반환합니다.
- subSet(E fromElement, E toElement): 세트에서 지정된 범위의 부분 세트를 반환합니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
public class T06TreeSetTest {
public static void main(String[] args) {
// TreeSet은 자동 정렬 기능이 들어가 있다.
TreeSet<String> ts = new TreeSet<String>();
List<String> abcList = new ArrayList<String>();
// 영어 대문자를 문자열로 변환하여 List에 저장하기
for(char ch='A'; ch<='Z'; ch++) {
String temp = String.valueOf(ch);
abcList.add(temp);
}
Collections.shuffle(abcList);
System.out.println("섞은 후의 abcList : " + abcList);
for(String str : abcList) {
ts.add(str);
}
System.out.println("TreeSet 데이터: " + ts);
System.out.println();
// TreeSet에 저장된 데이터 중 특정한 값보다 작은 데이터를 찾아
// SortedSet으로 반환하는 메서드가 있다.
// => headSet(기준값) : 기본적으로 '기준값'은 포함시키지 않는다.
// => headSet(기준값, 논리값) : 논리값이 true이면 '기준값' 포함함.
SortedSet<String> ss1 = ts.headSet("K");
System.out.println("K 이전 자료: " + ss1);
System.out.println("K 이전 자료(기준값 포함) : "
+ ts.headSet("K", true));
// '기준값'보다 큰 자료를 찾아 SortedSet으로 반환하는 메서드
// tailSet(기준값) : 기본적으로 '기준값'을 포함시킨다.
// tailSet(기준값, 논리값) : 논리값이 false이면 포함시키지 않는다.
SortedSet<String> ss2 = ts.tailSet("K");
System.out.println("K 이후 자료 : " + ss2);
System.out.println("K 이후 자료 (기준값 미포함): "
+ ts.tailSet("K", false));
// subSet(기준값1, 기준값2) : 기준값1 ~ 기준값2 사이의 값을 가져온다.
// ('기준값1' 포함, '기준값2' 미포함)
// subSet(기준값1, 논리값1, 기준값2, 논리값2) :
// 각 기준값 포함여부를 논리값으로 결정함.
System.out.println("K(포함)부터 N(미포함)까지: "
+ ts.subSet("K", "N"));
System.out.println("K(포함)부터 N(포함)까지: "
+ ts.subSet("K",true, "N",true));
System.out.println("K(미포함)부터 N(미포함)까지: "
+ ts.subSet("K",false, "N",false));
System.out.println("K(미포함)부터 N(포함)까지: "
+ ts.subSet("K",false, "N",true));
}
}
- equals() : 두 객체의 내용(값)이 같은지 비교하는 메서드
- hashCode() : 두 객체가 같은 객체인지를 비교하는 메서드
- 두 객체의 hashcode가 같다고 해서 두 객체가 반드시 같은 객체는 아니지만 두 객체가 같으면 반드시 hashcode 값이 같아야 한다.
- 클래스에서 hashCode()메서드를 오버라이드하지 않으면 두 객체가 같은 것으로 간주될 수 없다.
import java.util.HashSet;
import java.util.Set;
public class T07EqualsHashCodeTest {
/*
해시함수(hash function)는 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는
함수이다. 해시함수에 의해 얻어지는 값을 해시 값, 해시코드 또는 간단히 해시라고 한다.
HashSet, HashMap, Hashtable과 값은 객체를 사용할 경우
객체가 서로 같은지를 비교하기 위해 HashCode()와 equals()메서드를 사용한다.
그래서 객체가 서로 같은지 여부를 체크하기 위해 두 메서드를 재정의 해주어야 한다.
객체가 같은지 여부는 데이터를 추가할 때 검사한다.
- equals()는 두 객체의 내용(값)이 같은지 비교하는 메서드이고,
hashCode()는 객체에 대한 해시코드값을 가져오기 위한 메서드이다.
- equals()와 hashCode()메서드에 관한 규칙
1. 두 객체가 같으면 반드시 같은 해시코드를 가져야 한다.
2. 두 객체가 같으면 equals()메서드를 호출했을때 true를 반환해야 한다.
즉, 객체 a, b 가 같다면 a.equals(b)와 b.equals(a) 모두 true 이여야 한다.
3. 두 객체의 해시값이 같다고 해서 두 객체가 반드시 같은 객체라고 할 수 없다.
하지만, 두 객체가 같으면 반드시 해시값이 같아야 한다.
4. equals()를 재정의 해야 한다면, hashCode()도 재정의 해주어야 한다.
5. hashCode()는 기본적으로 힙메모리에 존재하는 각 객체에 대한 메모리 주소를
기반으로 한 정수 값을 반환한다. 그러므로, 클래스에서 hashCode()메서드를
재정의 하지 않으면 절대로 두 객체가 같은 객체로 간주될 수 없다.
*/
public static void main(String[] args) {
System.out.println("abcd".hashCode());
System.out.println("Aa".hashCode());
System.out.println("BB".hashCode());
Person p1 = new Person(1, "홍길동");
Person p2 = new Person(1, "홍길동");
Person p3 = new Person(1, "이순신");
System.out.println("p1.equals(p2) : " + p1.equals(p2));
System.out.println("p1 == p2 : " + (p1 == p2));
Set<Person> pSet = new HashSet<Person>();
System.out.println("add(p1) 성공여부 : " + pSet.add(p1));
System.out.println("add(p2) 성공여부 : " + pSet.add(p2));
System.out.println("p1, p2 등록 후 데이터");
for (Person p : pSet) {
System.out.println(p.getId() + " : " + p.getName());
}
System.out.println("add(p3) 성공여부 : " + pSet.add(p3));
System.out.println("p3 등록 후 데이터");
for (Person p : pSet) {
System.out.println(p.getId() + " : " + p.getName());
}
System.out.println("remove(p2) 성공여부 : "
+ pSet.remove(p2));
System.out.println("p2 삭제 후 데이터");
for (Person p : pSet) {
System.out.println(p.getId() + " : " + p.getName());
}
}
}
class Person {
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}
@Override
public boolean equals(Object obj) {
Person p = (Person) obj;
return (this.getId() == p.getId())
&& (this.getName().equals(p.getName()));
}
@Override
public int hashCode() {
return (name + id).hashCode();
}
}
'중급과정 > HighJava' 카테고리의 다른 글
[Java] 로또 구매 프로그램 예제 (ArrayList, HashSet, Collections) (0) | 2023.11.30 |
---|---|
[Java] 학생 리스트 정렬 (List, Comparable, Comparator) (0) | 2023.11.30 |
[Java] Thread(스레드)를 이용한 알파벳 대문자 출력과 출력순대로 순위 매기는 프로그램 작성예제 (0) | 2023.11.29 |
[Java] Thread(스레드)를 이용한 가위바위보 예제 (1) | 2023.11.29 |
[Java] 231121_1일차 ArrayList, LinkedList (0) | 2023.11.22 |