[Java] HashSet

19·2022년 11월 25일
0

Java

목록 보기
12/13

HashSet

Set 인터페이스를 구현한 가장 대표적인 컬렉션
Set 인터페이스를 구현했기 때문에, 순서를 유지하지 않고, 중복을 허용하지 않는다.

사용 예시

일반 예시)

Set set = new HashSet();

// Set에 랜덤 수를 담는다. (중복 허용 x)
for (int i=0; set.size()<6; i++) {
    int num = (int)(Math.random()*45) +1;
    set.add(new Integer(num));
}

// Set -> List
List list = new LinkedList(set);
Collections.sort(list);  // 오름차순 정렬
System.out.println(list);
[출력]
[7, 11, 17, 18, 24, 28]
  • 로또번호를 추출하는 예시
  • 바로 List에 랜덤 수를 담았다면 중복이 있었을 수 있다.
    • 중복을 허용하지 않아야할 때, Set을 사용한다.
  • Set에 랜덤 수를 담았을 때는 순서를 유지하지 않기 때문에 중구난방으로 저장된다.
    • List로 변환해 Collections의 sort()메소드로 정렬을 해줄 수 있다.
  • 필요에 따라 Set, List를 사용하고 필요하다면 변환하며 사용하는 것도 좋은 방법

객체를 저장할 때!!??

HashSet은 객체를 저장하기전에 기존에 같은 객체가 있는지 확인하며 중복을 허용하지 않는다.
객체를 저장할 때는, 저장할 객체의 equals()hashCode()를 호출해 중복을 체크한다.
-> equals()와 hashCode()를 오버라이딩해야 중복을 체크할 수 있다

예시)

class Person {
    String name;
    int age;
    
    Persion(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String toString() { return name + "-" + age; }

}
  • Person이라는 클래스가 있을 때, 이 클래스를 HashSet에 담으면 중복된 Person 인스턴스가 걸러질까?

HashSet set = new HashSet();
set.add(new Person("Saka",20);
set.add(new Person("Saka",20);
System.out.println(set);
[출력]
[Saka-20, Saka-20]
  • 동일한 인스턴스를 Set에 저장했다.
    • 올바른 동작은 Saka-20이 하나만 저장되야 하지만, 중복으로 저장되어있는것을 볼 수 있다.
    • Person 클래스의 equals(), hashCode() 메소드를 재정의해야한다.

Person 클래스에서 equals(), hashCode() 재정의

// 이름과 나이가 같은지를 Person 클래스에 맞게 재정의
@Override
public boolean equals(Object obj) {
    if (!(obj instanceof Person)) return false;
    Person p = (Person)obj;
    return name.equals(p.name) && age==p.age;
}

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

다시 실행하면 하나만 저장된다

[출력]
[Saka-20, Saka-20]


Set 순서x, 중복x
참조형을 Set에 담으려면 equals()와 hashCode()를 재정의해야 한다

profile
하나씩 차근차근

0개의 댓글