Java의 콜렉션 중 Set은 중복된 값이 들어가지 않는다.
어릴적 배웠었던 수학에서의 집합의 특성과 같다.
'여러대상의 모임이며, 순서가 없고 중복된 값이 없다'
Set의 구현체 중 HashSet을 이용해보겠다.
아래처럼 사용한다.
Test.java
public void 해시셋테스트() {
Set<Integer> set = new HashSet<Integer>(); set.add(1); set.add(2); set.add(2);
System.out.println(set); } |
결과 >>
[1, 2] |
결과를 보면, 중복된 값을 제거해서 저장해준다.
그러나, Wrapper class(Integer, String, Long...)가 아닌
내가 만든 Custom class로 하면, 중복된 데이터가 들어가버린다.
아래의 예를 한번 보자.
CreateObject.java
public class CreateObject { public Integer a; public Integer b; public CreateObject(Integer a, Integer b) { this.a = a; this.b = b; } } |
Test.java
public void 해시셋테스트() { Set<CreateObject> set = new HashSet<CreateObject>(); CreateObject obj1 = new CreateObject(1, 2); set.add(obj1); CreateObject obj2 = new CreateObject(1, 2); set.add(obj2);
System.out.println(set); } |
결과 >>
[CreateObject@5710fdb4, CreateObject@103ff589] |
obj에 들어있는 값이 서로 완전히 같은데도 불구하고,
둘은 다르다고 판단되어 Set에 따로따로 들어가버렸다.
왜 이런일이 발생하는 것인가?
그 이유는, HashSet이 내부적으로 해당 객체의 hashCode()와 equals()를 실행해보기 때문이다.
먼저 hashCode()메소드를 호출해서 hashCode가 같은지 판별한다.
만약 hashCode가 같으면 equals 메소드를 실행해보고 같은지 판별한다.
만약 같지 않으면, 두 객체는 같지 않은것이므로 equals메소드를 실행하지 않는다.
반면 잘 중복제거를 해줬던 Wrapper Class인 Integer.class의 hashCode메소드를 보니
override를 해서 value를 리턴하고 있다.
우리도 래퍼클래스처럼 Object.class의 hashCode(), equals 메소드를 사용할 것이 아니라,
오버라이드를 해줘야하는 것이다.
구현하기 나름이지만 예제를 한번 만들어보았다.
CreateObject.java
public class CreateObject { public Integer a; public Integer b;
public CreateObject(Integer a, Integer b) { this.a = a; this.b = b; }
@Override public int hashCode() { return new HashCodeBuilder().append(a).append(b).toHashCode(); }
@Override public boolean equals(Object obj) { CreateObject rhs = (CreateObject) obj; if (obj instanceof CreateObject) { return new EqualsBuilder().append(a, rhs.a).append(b, rhs.b).isEquals(); }
return false; } } |
hashCode메소드에서는 a, b 값으로 해시코드를 생성해서 리턴을 해주고,
equals메소드에서는 객체에 들어있는 모든 값이 같은지 판별해서 리턴한다.
참고로 Builder 클래스들은 common lang 라이브러리에 들어있다.
꼭 저렇게 안해도되고, 그냥 슈퍼클래스의 equals를 써도 상관 없다.
이렇게 구현한 후 다시 테스트코드를 실행시켜보니
중복된 데이터는 제거되어 들어갔다~
'개발 > JAVA' 카테고리의 다른 글
server to server에서 DATE 전송. jsp에서 포멧에 맞춰 출력하기. (0) | 2014.10.15 |
---|---|
[jUnit] class not found 에러 (0) | 2014.05.15 |
배열에 있는 값을 특정 구분자로 스트링으로 만들기 (0) | 2014.02.09 |
텍스트 파일 읽어오기 - (JAVA) (0) | 2014.01.11 |
C++ 의 virtual 함수. 가상화. JAVA랑 C++의 차이점 (1) | 2013.07.26 |