TreeSet은 두 가지 정렬 방법의 자연 분류 및 사용자 정의 정렬을 지원합니다. Treeset은 기본적으로 자연 분류를 사용합니다.
1. 자연 분류
TreeSet은 수집 요소의 비교 (Object OBJ) 메소드를 호출하여 요소 간의 크기 관계를 비교 한 다음 수집 요소를 오름차순 순서로 배열합니다. (비교를위한 presponse : 두 객체의 유형이 동일합니다).
Java는 비교 (Object OBJ) 메소드를 정의하는 비슷한 인터페이스를 제공합니다. 이는 인터페이스를 구현하는 클래스를 구현해야합니다. 객체가 다른 객체와 비교하기 위해 메소드를 호출 할 때, 예를 들어 OBJ1.comparto (OBJ2), 메소드가 0을 반환하면 양의 정수가 반환되면 OBJ1이 더 크다는 것을 의미합니다. OBJ2;
일반적인 Java 클래스는 비슷한 인터페이스를 구현하고 비교 크기에 대한 표준을 제공합니다. 비슷한 인터페이스를 구현하는 공통 클래스 :
트리셋에 객체를 추가하려고하면 객체의 클래스가 비슷한 인터페이스를 구현해야합니다.
다음 프로그램에서 오류 가보고됩니다.
클래스 err {} public class testtreeseterror {public static void main (String [] args) {treeset = new treeset (); 추가 (new err ())};설명 :
위의 프로그램은 Treeset 컬렉션에 2 개의 ERR 객체를 추가하려고합니다. 첫 번째 객체를 추가 할 때 TreeSet에 요소가 없으므로 두 번째 ERR 객체를 추가하면 TreeSet이 CompareTo (Object OBJ)를 호출합니다. 객체) 메소드는 컬렉션의 다른 요소와 비교됩니다. 해당 클래스가 비슷한 인터페이스를 구현하지 않으면 ClassCastException이 올라갑니다. 또한 TreeSet에서 요소의 첫 번째 요소를 제거하려고 할 때 ClassScastException 예외가 여전히 높아집니다.
비교 (Object OBJ) 메소드를 사용하여 객체를 비교할 때, 동일한 클래스의 두 인스턴스 만 크기를 비교할 수 있기 때문에 비교 객체 OBJ의 유형을 동일한 유형으로 캐스트해야합니다. 즉, 트리 셋에 추가 된 물체는 동일한 클래스이어야하며, 그렇지 않으면 클래스 캐스트 외환이 올라갑니다. 예를 들어, 트리 셋에 문자열 객체를 추가 할 때이 작업은 완전히 정상입니다. 두 번째 날짜 객체를 추가 할 때 Treeset은 컬렉션의 다른 요소와 비교하기 위해 객체의 비교 (Object OBJ) 메소드를 호출하며 현재 프로그램은 예외를 던집니다.
실제 프로그래밍에서 프로그래머는 자체 클래스를 정의하여 여러 유형의 객체를 TreeSet에 추가 할 수 있습니다. 사용자 정의 클래스는이 인터페이스를 구현할 때 비교 (Object OBJ) 메소드를 구현할 때 강제 유형이 수행되지 않습니다. . 전환하다. 그러나 TreeSet에서 수집 데이터를 작동 할 때 ClassCastExcrectio 예외는 여전히 다른 유형의 요소에 대해 발생합니다. (당신은 신중하게 읽은 후 이해할 것입니다)
Treeset 컬렉션에 객체가 추가되면 TreeSet은 객체의 비교 (Object OBJ) 메소드를 호출하여 크기를 컨테이너의 다른 객체와 비교 한 다음 빨간색 및 검은 색 트리 알고리즘을 기반으로 저장 위치를 결정합니다. 두 객체를 비교 (Object OBJ)에 의해 동일하게 비교되면 TreeSet은 동일한 위치를 저장하는 것으로 간주합니다.
트리 셋 컬렉션의 경우 두 개의 객체가 동일하지 않다고 판단하는 기준은 다음과 같습니다. 두 개로 처리됩니다.
다음 프로그램은 다음과 같습니다.
// Z 클래스는 Equals 메소드를 다시 작성하고 false를 반환합니다. } public boolean equals (object obj) {return false} public int compareto (object obj) {public class testtreeset {pub lic static void main (string [] args) {treeset set = new treeset (); z1 = new z (6); Add (z1); 세트); // 세트의 첫 번째 요소 (set.first ()). 보는 것은 9 System.out.println ((z) (set.last ()). age)가됩니다.프로그램 실행 결과 :
진실
[treeset.z@1fb8ee3, treeset.z@1fb8ee3]
9
설명 :
Z1 객체의 equals () 메소드는 항상 false를 반환하고 compareto (object obj) 메소드는 항상 1을 반환하기 때문에 동일한 객체가 프로그램에서 두 번 추가됩니다. 이런 식으로 TreeSet은 Z1 객체가 그 자체와 다르다고 생각할 것이므로 Treeset에 두 개의 Z1 객체를 추가하십시오. 트리셋 객체에 의해 저장된 두 가지 요소는 실제로 동일한 요소입니다. 따라서 Treeset Collection에서 첫 번째 요소의 연령 속성을 수정 한 후 TreeSet 컬렉션의 마지막 요소의 연령 속성도 변경됩니다.
요약 : 객체를 treeset에 넣고 해당 클래스의 equals () 메소드를 다시 작성 해야하는 경우,이 메소드가 CompareTo (Object OBJ) 메소드와 일관된 결과를 가져야합니다 두 개의 객체가 동등한 메소드 비교가 true를 반환 할 때 통과하고, 두 객체는 비교 (Object OBJ) 메소드를 비교하여 0을 반환해야합니다.
두 객체를 평등 메소드로 비교하지만 두 객체를 비교 (Object OBJ) 메소드로 비교하고 0을 반환하지 않으면 트리 셋이 다른 위치에 두 객체를 저장하여 두 객체 모두가 가능합니다. 세트 컬렉션의 규칙과 약간 다릅니다.
두 객체가 비교 (Object OBJ) 메소드를 비교하여 0을 반환하면 평등 메소드를 비교하여 False를 반환하면 두 객체가 비교 (Object OBJ) 메소드를 비교하는 것과 동일하기 때문에 TreeSet은 그것들을 다음에 저장하려고합니다. 같은 위치이지만 실제로는 작동하지 않으므로 (그렇지 않으면 객체가 하나만 남을 것입니다).
변동성 객체가 트리셋에 추가되고 후속 프로그램이 변한 객체의 특성을 수정하여 다른 물체의 크기 순서를 변경하게하지만 트리 세트는 순서를 다시 조정하지 않으며 저장 될 수도 있습니다. 트리셋 에서이 두 객체에서는 Equals 메소드를 비교하여 True를 반환하고 비교 (Object OBJ) 메소드는 0을 반환합니다.
다음 프로그램은 다음과 같습니다.
Class r {int count (int count) {this.count = count; if (r) {r) obj; 클래스 testhashset2 {public static void main (string [] args) {new Hashset (); r (9); Hs.Add (new r (-2)); .eritator (); r first = (r) it.next (); none sequential system.out.println (hs); -3 r Object? " + hs. contains (new r (-3)); // false system.out.println ("hs는 5 인 r 객체를 포함합니까? " + hs.crantains (new r (new r) 5)));}}}프로그램 실행 결과 :
[r (count attribute : -3), r (count 속성 : -2), r (count attribute : 5), r (count attribute : 9)]
[r (count attribute : 20), r (count 속성 : -2), r (count attribute : 5), r (count attribute : -2)]
[r (count attribute : 20), r (count 속성 : -2), r (count attribute : 5), r (count attribute : -2)]
[r (count attribute : 20), r (count 속성 : -2), r (count attribute : -2)]
설명 :
위 프로그램의 R 객체는 평등 메소드와 비슷한 메소드 클래스의 정상적인 재 작성입니다. 프로그램의 첫 번째 출력이 순서대로 정렬되어 있음을 알 수 있습니다. R 객체의 카운트 속성이 변경되면 프로그램의 출력 결과도 중복 요소를 변경하고 포함합니다. 트리 셋 컬렉션의 가변 요소의 특성이 변경되면, 뷰에서 객체가 삭제되면 TreeSet은 삭제되지 않습니다 (컬렉션에서 원래 요소조차 수정되지 않았지만 수정 된 요소조차도 수정되지 않았습니다. 요소를 삭제할 수 없습니다)
-2가있는 r 객체가 삭제되지 않으면 프로그램은 5 인 r 객체를 삭제할 수 있습니다.
요약 : 해시 세트를 사용하면 이러한 객체를 처리 할 때 매우 복잡하고 오류가 발생합니다. 프로그램을보다 강력하게 만들려면 해시 세트 및 트리 셋 컬렉션에 불변의 물체 만 배치하는 것이 좋습니다.
2. 사용자 정의 정렬
자연스러운 종류의 트리 셋은 수집 요소의 크기를 기반으로하며 TreeSet은 오름차순 순서로 배열합니다. 하강 순서와 같은 사용자 정의 정렬을 구현 해야하는 경우 비교기 인터페이스를 사용할 수 있습니다. 이 인터페이스에는 O1 및 O2의 크기를 비교하는 데 사용되는 int 비교 (t o1, t o2) 메소드가 포함되어 있습니다.
맞춤형 정렬을 구현 해야하는 경우 TreeSet Collection 객체를 작성할 때 비교기 객체를 제공하고 TreeSet 컬렉션과 연결할 수있는 비교기 객체를 제공해야하며 비교기 객체는 컬렉션 요소의 분류 로직을 담당합니다.
다음 프로그램은 다음과 같습니다.
클래스 M {int Age; main (string [] args) {treeset ts = new treeset (new 비교 () {public int compar (object o1, object o2) {m m1 = (m) o1; m m2 = (m) o2; if (m1. Age> age) {return} else (m1.age =} {return 1}); ts.add (new m (-3));프로그램 실행 결과 :
[M 객체 (연령 : 9), M 객체 (연령 : 5), M 객체 (Age : -3)]
설명 :
위의 프로그램은 TS 컬렉션의 정렬을 담당하는 비교기 인터페이스의 익명 내부 클래스 객체를 만듭니다. 따라서 TS 컬렉션에 M 객체를 추가하면 M 클래스가 비슷한 인터페이스를 구현할 필요가 없습니다. 현재 Treeset은 M 객체를 통해 크기를 비교할 필요가 없지만 Treeset과 관련된 비교기 객체를 비교할 필요가 없기 때문입니다. 수집 요소의 정렬을 담당합니다. 사용자 지정 정렬을 사용할 때 TreeSet은 수집 요소 자체의 크기에 관계없이 컬렉션 요소를 정렬하지만 비교기 객체는 수집 요소의 정렬 규칙을 담당합니다.