HashSet, HashMap에 Custom class 중복 제거하기

Deduplicate custom class in HashSet and HashMap

Posted by dydtjr1128 on April 25, 2019 · 5 mins read Java
HashSet, HashMap에 Custom class 중복 제거하기
public class People {
    String name;
    int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

위와 같은 People 클래스가 존재할 때, HashMap과 HashSet에 객체를 아래와 같이 넣을 수 있다.

public class Main {

    public static void main(String[] args) {
        People people1 = new People("choi", 26);
        People people2 = new People("kim", 25);

        Set<People> hashSet = new HashSet<>();
        HashMap<People,String> hashMap = new HashMap<>();
        hashSet.add(people1);
        hashSet.add(people2);
        hashMap.put(people1,"Seoul");
        hashMap.put(people2,"Busan");
    }
}

하지만 동일한 내용을 가진 객체를 넣게되면 어떻게 될까?

public class Main {

    public static void main(String[] args) {
        People people1 = new People("choi", 26);
        People people2 = new People("choi", 26);

        Set<People> hashSet = new HashSet<>();
        HashMap<People,String> hashMap = new HashMap<>();
        hashSet.add(people1);
        hashSet.add(people2);
        hashMap.put(people1,"Seoul");
        hashMap.put(people2,"Busan");

        System.out.println("hashSet.size() : " + hashSet.size());
        System.out.println("hashMap.size() : " + hashMap.size());
        System.out.println("people1.hashCode(), people2.hashCode() : "
                + people1.hashCode() + " " + people2.hashCode());
        System.out.println("identityHashCode(people1), identityHashCode(people2) : "
                + System.identityHashCode(people1) + " " + System.identityHashCode(people2));
        System.out.println("people1==people2 : " + (people1 == people2));
        System.out.println("people1.equals(people2) : " + people1.equals(people2));
    }
}
hashSet.size() : 2
hashMap.size() : 2
people1.hashCode(), people2.hashCode() : 460141958 1163157884
identityHashCode(people1), identityHashCode(people2) : 460141958 1163157884
people1==people2 : false
people1.equals(people2) : false

people1people2를 다른 객체로 인식하기 때문에 두 객체 모두 key 값이 될 수 있다.
중복된 내용을 지우고 싶은 경우가 생긴다면 HashMap, HashSet 모두 단순히 hashcode()만으로 판별하는 것이 아닌 equals() 메소드 또한 사용하기 때문에 두가지 메소드를 오버라이드하여 구현해 주어야 한다.

public class People {
    String name;
    int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object a) {
        People obj = (People) a;
        return (obj.name == this.name && obj.age == this.age);
    }

    @Override
    public int hashCode() {
        return (name + age).hashCode();
    }
}

hashcode()를 오버라이드 한 메소드를 구현하고, equals()에 대한 메소드 또한 오버라이드 한 메소드를 구현하여 실행하게되면 원하는 대로 중복된 값이 제거된 것을 알 수 있다.

hashSet.size() : 1
hashMap.size() : 1
people1.hashCode(), people2.hashCode() : -1361225853 -1361225853
identityHashCode(people1), identityHashCode(people2) : 460141958 1163157884
people1==people2 : false
people1.equals(people2) : true