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 |