Hash set
- 순서 X 중복 X
HashSet은 객체들을 순서없이 저장하고 동일한 객체는 중복 저장하지 않는다.
HashSet이 판단하는 동일 객체란 꼭 같은 인스턴스를 뜻하지 않는다.
HashSet은 객체를 저장하기 전에 객체의 hashCode()메소드를 호출해서 해시코드를 얻어내고,
그리고 이미 저장된 객체의 해시코드와 비교한다.
만약 동일한 해시코드가 나온다면 equals() 메소드로 두 객체를 비교해서
true가 나온다면 동일한 객체로 판단하고 중복 저장을 하지 않는다.
이런 순서로 동일 객체인지 확인하기 때문에
서로 다른 String 객체인 경우에도 같은 문자열을 갖고 있을 때 중복으로 취급될 수 있다.
문자열을 HashSet에 저장하는 경우,
같은 문자열을 갖는 String 객체는 동등한 객체로 간주되고
다른 문자열을 갖는 String 객체는 다른 객체로 간주되는데,
그 이유는 String 클래스가 hashCode()와 equals()메소드를 재정의해서
같은 문자열의 경우 hashCode()의 리턴값을 같게,
equals()의 리턴값을 참으로 나오게 하기 때문이다.
String 객체 뿐 아니라 임의의 객체들도 hashCode()메소드와 equals()메소드를 재정의하면
서로 다른 객체들이라도 중복으로 취급되게 만들 수 있다. (아래의 EX01 참고)
자주 사용하는 메소드
- .add( ): 중복 값은 추가해도, 변화 X
- .clear()
- .size()
※ 왜 System.out.println(set.add(r)); 을 하면 true/false로 출력되는 지 모르겠어서, 일단 적어둔다.package collection; import java.util.HashSet; import java.util.Scanner; public class Set01 { public static void main(String[] args) { HashSet<Integer> set = new HashSet<Integer>(); //set.add() set.add(104); set.add(10); set.add(1100); set.add(104); //중복 값 추가해도 변화 X System.out.println(set.size()); //4개를 추가 했지만, size는 3 } }
set.clear(); System.out.println(set); //[] while (set.size() < 6) { int r = (int)(Math.random() * 45 + 1); set.add(r); System.out.println(set.add(r)); //이게 왜 true false? } System.out.println(set);
- .addAll()
- set에 .addAll() : 순서가 섞이며 연결됨(기준?)
- list에 .addAll() : 순서가 유지되며 연결됨
//.addAll() Set<Integer> set = new HashSet<Integer>(); set.add(100); set.add(100); set.add(10); set.add(10); System.out.println(set); //[100, 10] List<Integer> list = new ArrayList<Integer>(); list.add(5); list.add(60); list.add(65); //set에 .addAll(list) //순서가 섞이며 연결됨 (기준?) set.addAll(list); System.out.println(set); //[65, 100, 5, 10, 60] //list에 .addAll(set) //순서 유지되며 연결됨(list 뒤에 set) list.addAll(set); System.out.println(list); //[5, 60, 65, 65, 100, 5, 10, 60]
- .remove()
- .contains()
//set도 .remove(), .contains() 등 사용가능 set.remove(60);//set에서 60이 삭제됨 [65, 100, 5, 10, 60] -> [65, 100, 5, 10] System.out.println(set); //[65, 100, 5, 10] //출력 for (Integer i : set) { System.out.println(i); }
Set에서 Iterator 사용하기
Set 객체는 .get() 메서드가 제공되지 않으므로 다음과 같이 iterator를 활용하여 객체를 순회함
Iterator<Integer> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
EX01. HashSet의 동일 객체 취급 기준 확인하기
package collection;
import java.util.HashSet;
import java.util.Set;
class Member{
public String name;
public int age;
public Member(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
return name.hashCode() + age;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Member){
Member member = (Member) obj;
return member.name.equals(name) && member.age == age;
}else {
return false;
}
}
}
public class Set04 {
public static void main(String[] args) {
Set<Member> set = new HashSet<Member>();
//Member m1 = new Member("홍길동", 150);
//Member m2 = new Member("홍길동", 150);
set.add(new Member("홍길동", 150));
set.add(new Member("홍길동", 150));
System.out.println(set.size()); //1
System.out.println(set); //[collection.Member@33a4444]
}
}
→ hashCode() 메소드와 equals() 메소드를 재정의하면,
같은 객체로 취급되어 중복으로 추가되지 않는 다는 것을 알 수 있다.
'BackEnd > Java' 카테고리의 다른 글
[Java] 스택(Stack), 큐(Queue) (0) | 2021.07.19 |
---|---|
[Java] 맵 Map (0) | 2021.07.19 |
[Java] VirtualBox 설치 (0) | 2021.07.19 |
[Java] Linked List (0) | 2021.07.18 |
[Java] ArrayList (0) | 2021.07.15 |
댓글