기초 문법 알아보기 Java

컬렉션 프레임웍 Collection Framework : HashSet

람대리 2024. 4. 29. 14:32
728x90

HashSet이란

- Set 인터페이스를 구현한 가장 대표적인 컬렉션

- Set 인터페이스의 특징대로 HashSet은 중복된 요소를 저장하지 않는다.

- 컬렉션 내의 중복 요소들을 쉽게 제거할 수 있다.

- 저장순서를 유지하고자 한다면 LinkedHashSet을 사용해야한다.

 

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]);
}

System.out.println(set); // 실행결과: [1,1,2,3,4]

-  '1'이 두 번 출력되었는데, 하나는 String 인스턴스이고 다른 하나는 Integer 인스턴스로 서로 다른 객체이므로 중복으로 간주하지 않는다.

 

class HashSetEx{
	public static void main(String[] args){
    	
        HashSet set = new HashSet();
        
        set.add(new String("abc"));
        set.add(new String("abc"));
        set.add(new Person2("David",10));
        set.add(new Person2("David",10));
        
        System.out.println(set); // 출력 : [abc, David:10]
    }
}

class Person2{
	String name;
    int age;
    
    Person2(String name, int age){
    	this.name = name;
        this.age = age;
    }
    
    public boolean equals(Object obj){
    	if(obj instanceof Person2){
        	Person2 tmp = (Person2)obj;
            return name.equals(tmp.name) && age == tmp.age;
        }
        
        return false;
    }
    
    public int hashCode(){
    	return (name+age).hashCode();
    }
    
    public String toString(){
    	return name + ":" + age;
    }
}

- HashSet의 add메서드는 기존에 저장된 요소와 같은 것인지 판별하기 위해 추가하려는 요소의 equals(), hashCode()를 호출하기 때문에 equals()와 hashCode()를 목적에 맞게 오버라이딩해야 한다.

 

hashCode() 사용조건

- 실행 중인 동일한 객체에 대해서 여러 번 hashCode()를 호출해도 동일한 int값을 반환해야한다. 하지만 실행시마다 동일한 int값을 반환할 필요는 없다.

Person2 p = new Person2("David",10);

int hashCode1 = p.hashCode();
int hashCode2 = p.hashCode(); // hashCode1과 hashCode2는 같은 값이 나온다.

p.age = 20;
int hashCode3 = p.hashCode(); // hashCode3는 다른 값이 나온다.

 

- equal메서드를 이용한 비교에 의해서 true를 얻은 두 객체에 대해 각각 hashCode()를 호출해서 얻은 결과는 반드시 같아야 한다.

Person p1 = new Person2("David",10);
Person p2 = new Person2("David",10);

boolean b = p1.equals(p2); // b의 값이 true라면

int hashCode1 = p1.hashCode();
int hashCode2 = p2.hashCode(); // hashCode1과 hashCode2의 값은 같다.

 

- equal메서드를 호출했을 때 false를 반환하는 두 객체는 hashCode() 호출에 대해 같은 int값을 반환하는 경우가 있어도 괜찮지만, 해싱(hashing)을 사용하는 컬렉션의 성능을 향상시키기 위해서 다른 int값을 반환하는 것이 좋다.