HashSet

정순동·2023년 12월 21일
0

자바기초

목록 보기
63/89

HashSet은 Set인터페이스를 구현한 대표적인 컬렉션이고 Set인터페이스의 특징대로 중복된 요소를 저장하지 않는다.
HashSet에 새로운 요소를 추가할 때는 add(), addAll()메서드를 사용한다. 이 때 이미 저장된 내용을 또 다시 저장하려고 하면 false를 반환하며 저장 실패를 알린다.

ArrayList와 같이 List인터페이스를 구현한 컬렉션클래스와는 달리 HashSet은 저장순서를 유지하지 않으므로 저장순서를 유지하고자 한다면 LinkedHashSet을 사용해야 한다.

위 표에서 load factor는 컬렉션 클래스에 저장공간이 가득 차기 전에 미리 용량을 확보하기 위한 것으로 이 값을 0.x로 지정한다면 x0% (0.8 = 80%)만큼 채워졌을 때 용량을 두 배로 늘린다. 기본값은 0.75이다.

Stream관련 메서드 들은 스트림 게시글을 참고하면 된다.

import java.util.*;

public class HashSetExample {
    public static void main(String[] args) {
        Object[] objArr = {"1", new Integer(1),"2","2","3","3","4","4","4"};
        Set set = new HashSet();

        for(int i = 0; i < objArr.length; i++) {
            set.add(objArr[i]); // HashSet에 objArr의 요소들을 저장한다.
        }
        // HashSet에 저장된 요소들을 출력한다.
        System.out.println(set);
        // HashSet에 저장된 요소들을 출력한다.(Iterator이용)
        Iterator it = set.iterator();

        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

위 코드는 objArr를 HashSet에 저장하는 코드이다. 결과를 보면 [1, 1, 2, 3, 4]로 중복이 제거된 것을 볼 수 있다.
1이 두 개인 이유는 서로 타입이 다르기 때문에 다른 값으로 간주하기 때문이다.

import java.util.HashSet;

public class HashSetExample3 {
    public static void main(String[] args) {
        HashSet set = new HashSet();
        set.add("abc");
        set.add("abc");
        set.add(new Person("David", 10));
        set.add(new Person("David", 10));

        System.out.println(set);
    }
}

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

만약 위 코드를 실행하면 "David:10"이 두번출력될까? 정답은 yes이다 HashSet의 add메서드는 새로운 요소를 추가하기전에 요소의 equals()와 hashCode()를 호출하기 때문에 서로 다르다고 판단하고 HashSet에 정상적으로 추가되기 때문이다.(기본 equals()는 주소로 비교하기에) 이럴 때에는 아래와 같은 코드를 추가하면 해결된다.

	@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); //int hash(Object... values)
    }

최근에는 hashCode()를 아래와 같이 오버라이딩 하기도 한다.

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

주의 Object클래스가 아닌 Objects클래스임. 또한 hash(Object... values)처럼 가변인자이다.

0개의 댓글