머리말
삽입 정렬, 힐 정렬 및 병합 정렬과 같은 알고리즘을 수행 할 때 두 객체의 "크기"를 비교하는 비교 작업을 말할 때. 정수 I> J의 비교 방법을 이해하기 쉽지만 여러 객체를 정렬 할 때 두 객체의 "크기"를 어떻게 비교합니까? STU1> STU2의 이러한 비교는 컴파일하기가 불가능합니다. JDK는 두 객체의 크기를 비교하는 방법에 대한 문제를 해결하기 위해 java.lang.Comparable 및 java.util.Comparator 제공합니다.
1. 자연 분류 : java.lang.comparable
비교 인터페이스에는 compareTo(Object obj) 제공되는 메소드가 하나 뿐이며이 메소드의 리턴 값은 int입니다. 리턴 값이 양수 인 경우, 현재 객체 (메소드를 호출하는 객체)가 OBJ 객체보다 "큰"임을 의미합니다. 그렇지 않으면 "작은"입니다. 0이면 두 객체가 동일하다는 것을 의미합니다.
다음은 비슷한 인터페이스를 구현하는 학생 수업입니다.
공개 수업 학생은 비슷한 {private int id; 개인 문자열 이름; 공개 학생 () {super (); } @override public int compareto (object obj) {if (obj instance of student) {student stu = (학생) obj; return id -stu.id; } 반환 0; } @override public String toString () {return "<" + id + "," + name + ">"; }} 학생은 자연 분류 인터페이스를 비교할 수 있습니다. 그렇다면이 인터페이스를 어떻게 사용하여 일련의 학생 객체를 정렬합니까? 우리가 배열을 학습 할 때, 우리는 클래스를 사용하여 정수 배열을 정렬했습니다 : java.util.Arrays . 우리는 배열 정렬 메소드를 사용하여 정수 배열을 정렬합니다. API 문서를 뒤집은 후 배열은 sort(Object[] obj) 포함하여 많은 오버로드 형식의 정렬 방법을 제공한다는 것을 알게됩니다. 분류 프로세스 동안 두 객체의 "크기"를 비교할 때 비교 가능한 인터페이스를 사용하여 비교 방법을 비교합니다.
public class comparetest {public static void main (String [] args) {학생 stu1 = new Student (1, "little"); 학생 stu2 = 신입생 (2, "Cyntin"); 학생 stu3 = 신입생 (3, "Tony"); 학생 stu4 = 신입생 (4, "gemini"); 학생 [] stus = 신입생 [4]; stu0] = stu1; stu1 [1] = stu4; Stus [2] = stu3; stu3] = stu2; System.out.println ( "배열 :" + arrays.tostring (stus)); Arrays.sort (stus); System.out.println ( "sort :" + arrays.tostring (stus)); }} 학생 배열에서 요소가 추가되는 순서는 학생 ID에 따라 추가되지 않습니다. Arrays.sort(stus) 를 호출 한 후 학생 배열을 정렬하십시오. 어떤 정렬 알고리즘을 구현하는 데 사용하든 두 객체의 "크기"작업을 비교해야합니다. 그렇다면 두 객체의 "크기"를 어떻게 비교합니까? 학생이 구현 한 비슷한 인터페이스가 작동합니다. 정렬 방법은 비교할 수있는 객체를 비교하고 비교 방법을 호출하여 리턴 값에 따라이 두 객체의 "크기"를 판단합니다. 따라서이 예에서 원래의 학생 외 배열 분류는 학생 번호로 정렬 된 학생 배열이됩니다.
그러나 분류 알고리즘이 학생 수업에 바인딩되고 학생은 하나의 정렬 알고리즘 만 가지고 있음을 알았습니다. 그러나 이것은 실제 사회에서는 그렇지 않습니다. 학생 번호별로 정렬하고 싶지 않다면 어떻게해야합니까? 학생들을 이름으로 정렬하고 싶다면 어떻게해야합니까? 학생 클래스의 비교 인터페이스의 비교 방법 만 수정하고 이름으로 정렬하도록 변경할 수 있습니다. 동일한 시스템에 두 개의 작업이 있으면 하나는 학생 번호별로 정렬되고 다른 하나는 이름별로 정렬됩니다. 학생 수업 기관에서 두 가지 비교 방법 구현을 작성하는 것은 불가능합니다. 이 관점에서 비교할 수있는 한계가 있습니다. JDK는이 단점을 보충하기 위해 다른 분류 방법을 제공합니다.이 방법은 다음과 같은 비교기 분류입니다.
2. 비교기 분류 : java.util.comparator
비교기 분류 인터페이스가 제공되는 이유는 때로는 여러 가지 방식으로 동일한 객체를 정렬해야하며 비교할 수있는이 자연스러운 정렬을 구현할 수 없기 때문입니다. 또한 비교기 인터페이스의 장점 중 하나는 비교 분류 알고리즘을 특정 엔티티 클래스에서 분리한다는 것입니다.
API를 살펴보면 오버로드 된 배열 형태가 있음을 알 수 있습니다 .SORT : sort(T[] a, Comparator<? super T> c) . 이 방법은 제네릭을 사용하여 아직 언급하지 않은이 방법의 매개 변수를 작성합니다. 이 형식으로 이해할 수 있습니다. sort(Object[] a, Comparator c) 는 비교 정렬 알고리즘에 따라 객체 배열을 정렬하는 것을 의미합니다. 비교기 인터페이스에 정의 된 두 가지 방법은 compare(Object o1, Object o2) 및 equals 방법입니다. equals 메소드에는 모든 객체에 대한 메소드가 있으므로 비교기 인터페이스를 구현할 때 equals 메소드를 재정의하는 대신 compare 방법을 무시하면됩니다. 비교기 인터페이스에서 동등한 방법에 Object.equals(Object) 설명은 다음과 같습니다. 우리는 첫 번째 문장 만 알아야하며 괜찮습니다. 즉, Equals 메소드의 구현을 표시하지 않더라도 객체 클래스의 Equals 메소드를 사용하더라도 코드는 여전히 안전하기 때문에 Equals 메소드를 구현하는 방법에 대해 생각할 필요가 없습니다.
그래서 비교기와 정렬하는 코드를 작성해 봅시다. 여전히 학생 수업에서 수행되지만 비슷한 인터페이스는 구현되지 않습니다. 비교기 구현 클래스는 하나의 메소드를 구현하기 위해 디스플레이 만 사용하므로이를 구현하기 위해 클래스를 작성할 필요가 없습니다. 비교기를 사용해야 할 때 비교기를 구현하기 위해 익명의 내부 클래스를 작성할 수 있습니다.
다음은 이름별로 정렬하는 방법입니다.
public void sortbyname () {학생 stu1 = 신입생 (1, "little"); 학생 stu2 = 신입생 (2, "Cyntin"); 학생 stu3 = 신입생 (3, "Tony"); 학생 stu4 = 신입생 (4, "gemini"); 학생 [] stus = 신입생 [4]; stu0] = stu1; STU1; STU4; stu2] = stu3; stu3] = stu2; System.out.println ( "배열 :" + arrays.tostring (stus)); arrays.sort (stus, new comporator () {@override public int compart (object o1, object o2) {if (o1 studentof studentof student의 && o2 학생) {학생 s1 = (학생) o1; 학생) o2; // return s1.getid () - s2.getid (); eh id range s1.getname (). // 이름으로 정리} return 0; System.out.println ( "정렬 :" + arrays.tostring (stus)); }학생 번호별로 학생을 정렬 해야하는 경우 학생 수업을 수정하지 않고 분류 방법에서 비교기를 구현하는 내부 수업에서 코드를 수정하면됩니다.
참고 : 물론, 학생 수업을 사용하여 비교기 인터페이스를 구현하여 학생이 (IS A) 비교기 (비교기)를 구현할 수 있습니다. 이런 종류를 사용해야 할 때는 학생을 비교기로 사용하십시오. 학생은 비교기이기 때문에 학생을 정렬 방법으로 전달할 수 있습니다. 그러나 이러한 코드는 우수한 코드가 아닙니다. 비교기를 사용하는 중요한 이유 중 하나는 비교 알고리즘을 특정 클래스에서 분리하고 클래스 간 커플 링을 줄일 수 있기 때문입니다.
TreeSet은 트리 셋의 두 가지 생성자 방법에 해당하는 비교 방법을 모두 지원합니다.
1. treeset () : treeset의 요소에 의해 구현 된 비교 가능한 인터페이스의 비교 방법에 따라 비교 및 정렬
2. Treeset (비교기 비교기) : 주어진 비교기 비교기에 따라 트리 셋의 비교 및 정렬 요소
트리 셋에 요소를 추가 할 때 트리 셋은 요소를 정렬합니다. 자연 순서 또는 비교기와 정렬할지 여부는 TreeSet 구조가 작성되는 방식에 따라 다릅니다. 물론 첫 번째 요소를 추가 할 때 비교할 수 없습니다. 트리 세트에는 요소가 없습니다. 누구와 비교할 수 있습니까?
아래에서는 두 가지 정렬 및 비교 방법을 사용한 TreeSet 테스트 코드가 제공됩니다.
/ *** Natural Sort 사용* 학생은 비슷한 인터페이스를 구현해야합니다. 그렇지 않으면 ClassCastException이 던져집니다*/ public void testSortedSet3 () {Student STU1 = new Student (1, "little"); 학생 stu2 = 신입생 (2, "Cyntin"); 학생 stu3 = 신입생 (3, "Tony"); 학생 stu4 = 신입생 (4, "gemini"); SortedSet Set = New Treeset (); set.add (stu1); set.add (stu3); // 학생이 비슷한 인터페이스를 구현하지 않으면 ClassCastException Set.Add (stu4); set.add (stu2); set.add (stu4); set.add (신입생 (12, "little"); System.out.println (set); } / *** 비교기를 정렬에 사용하십시오* 학생은 비교 가능한 인터페이스를 구현하지 않고 간단한 Java 클래스 일 수 있습니다*/ public void testsortedset3 () {Student STU1 = new Student (1, "little"); 학생 stu2 = 신입생 (2, "Cyntin"); 학생 stu3 = 신입생 (3, "Tony"); 학생 stu4 = 신입생 (4, "gemini"); SortedSet Set = new Treeset (new Comporator () {@override public int compar (object o1, object o2) {if (o1 studentof studentof studentof student의 && o2 학생) {학생 s1 = (학생) o1; 학생 s2 = (학생) o2; 반환 s1.getname (). compareto (s2. getname ());}); set.add (stu1); set.add (stu3); set.add (stu4); set.add (stu2); set.add (stu4); set.add (신입생 (12, "little"); System.out.println (set); } 또한 도구 클래스 java.util.Collections 소개하십시오. 이것은 컬렉션 인터페이스가 아닙니다. 컬렉션은 배열 클래스와 매우 유사합니다. 배열은 어레이 작업, 정렬을 찾기위한 일련의 정적 메소드를 제공합니다. 컬렉션은 또한 일련의 방법을 제공하지만 컬렉션을 처리하는 데 사용됩니다. 컬렉션 클래스는 컬렉션 인터페이스와 매우 유사하지만 컬렉션 이름으로 속지 마십시오. 컬렉션 인터페이스 및 하위 인터페이스 만 처리 할 수있는 구현 클래스는 아니지만 맵 인터페이스의 구현 클래스를 처리 할 수도 있습니다.
요약
이것은 자바에서 자연 분류 및 비교기 분류에 대한 소개의 끝입니다. 이 기사는 여전히 비교적 상세합니다. 나는 그것이 당신의 공부 나 일에 당신을 도울 수 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다.