JAVA

[Java] TreeSet의 구조와 주의사항

코카멍멍 2024. 2. 29. 21:01
반응형

TreeSet 구조

TreeSet은 필드로 NavigableMap인터페이스를 필드로 가지고 있으며

TreeMap클래스가 필드인NavigableMap 인터페이스를 구현하는 구조를 가지고 있습니다.

TreeSet 생성자가 호출되면 m 필드에 TreeMap클래스가 할당되게 됩니다.
저는 이 TreeSet을 사용하면서 예상한 결과값이랑 다르게 결과가 나와서 어떤 이유인지 찾아보기로 했습니다.

문제점

결과

x만 비교하여 TreeSet 자료구조를 사용했을 때는 1개의 요소밖에 존재하지 않았습니다. HashSet이라면 객체의 hashCode()와 equals()를 비교하여 객체의 수가 2라는 결과가 나왔을텐데 말이죠...

결과

x와 y 모두 비교하는 코드를 작성했습니다. 이번에는 원하는 결과가 나왔습니다. 왜 이런 결과가 나오는지 의문이 드네요 원인에 대해 코드를 한번 분석해보겠습니다.

TreeMap Put() 실제 객체를 추가할 때

원인

TreeSet 자료구조는 필드로 TreeMap을 가지고 있으며 저장하는 객체를 key: value로 TreeMap에 저장하는 방식을 갖고 있습니다. key는 업캐스팅하지 않은 객체를 의미하며 value는 업캐스팅한 Object객체를 의미합니다. 실제 객체를 추가할 때는 key값으로 객체의 필드값을 받아오고 사용자가 정의한 compare함수를 통해 비교합니다. 값이 동일하다면 동일한 객체로 인식하고 현재 노드에 업캐스팅한 Object를 저장하는 방식입니다.
HashMap과는 다른 방식인 것입니다. HashMap은 객체의 hashCode()와 equals()로 비교한다면 TreeMap은 사용자가 지정한 Comparator를 이용하여 같은 값인지 확인합니다. 그렇기에 객체의 equals(), hashCode()함수를 재정의 하지 않아도 논리적인 동치성을 비교할 수가 있습니다.

간단하게 정리

  • HashSet
    동일한 객체인지 비교할 때 hashCode()와 equals()를 기반으로 동일한지 비교하기 때문에 논리적 동치성을 비교하기 위해서는 hashCode()와 equals()의 재정의가 필요하다.
  • TreeSet
    동일한 객체인지는 사용자가 직접 정의하기 때문에 논리적으로 어디까지 같다고 할 것인지 Comparator를 정의해줘야 한다.
반응형