본문 바로가기
java

java 중복 없애주는 set, 객체는?

by socialcomputer 2022. 5. 11.

코딩테스트 문제를 풀때 중복되는 객체를 걸러줬으면 했는데 생각처럼 되지 않아서 어떻게 해야 하는지 찾아보았다. 

안에 내용은 똑같은데 아무리  set에 넣어도 중복이 제거되지 않고 add되는 것이 이상했다. 

결론은, 객체가 아닐 경우엔 중복을 자동으로 제거해줄 수 있지만, 객체일 경우 중복을 제거하려면 추가로 구현해야 할 것이 있다. 

참고로, 문자열로부터 정수의 해시코드값을 얻고
int hashCode = "keyValue".hashCode(); // 해시코드 : 492250706
hash table의 크기로 나눈 나머지의 인덱스에 데이터가 저장된다. 

그 이유에는 hash set이 데이터를 저장할 때 hash table을 사용하기 때문이다. 저장할 데이터로부터 hashcode를 얻고 그것을 key로 하여 데이터를 저장한다. 객체일 경우 주소값으로부터 hashcode를 얻기 때문에 객체 내의 내용이 같다고 하더라도 주소값이 다르기 떄문에 다른 key값을 가지게 되어 계속 set에 추가된다. 

hash set 에서 객체의 내용이 같으면 같다는 것을 설정하기 위해 두가지 메소드들을 재정의 해줘야 한다. 

  • int hashCode()     
  • boolean equals(Objdect o)
package study_java;

import java.util.HashSet;

/**
 * hashset에서 객체를 추가할때 중복을 제거하지 못하는데
 * 메소드를 재정의 하여 가능하게 할 수 있다
 */
public class Set_Object_Duplicate {
    public static void main(String[] args) {

        HashSet<Location> set = new HashSet<>();
        set.add(new Location(1, 1));
        set.add(new Location(1, 1));
        set.add(new Location(1, 1));
        System.out.println(set.size());// ->1이 나옴
    }
    static class Location{
        private final int x;
        private final int y;
        public Location(int x, int y){
            this.x = x;
            this.y = y;
        }

        @Override
        public int hashCode(){
            return (x+":"+y).hashCode();
        }
        @Override
        public boolean equals(Object o){
            Location obj = (Location) o;
            return obj.x==x && obj.y==y;
        }
    }

}
이 유튜브를 보고 공부했다!!!

 


여기서 메소드를 오버라이딩하여 재정의 해줄때 @Override를 붙여주지 않아도 정상적으로 작동한다. 

붙여주지 않아도 작동은 하지만 붙여서 구현해주는게 좋다고 한다. 

- 구현 클래스에 @Override 어노테이션이 붙어있는 메소드가 구현되어 있는 상태에서 인터페이스의 구조가 변경 되면서 해당 메소드를 삭제하면 컴파일 에러가 나게 된다고 한다. 안정장치처럼 생각하고 대부분 붙여주는 게 좋은듯 하다. 

댓글