Comparable 인터페이스
자기 자신과 파라미터를 비교한다. compareTo 메서드를 오버라이딩해서 구현한다.
import java.io.*;
import java.util.*;
class Animal implements Comparable<Animal> {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Animal o) {
return this.age - o.age;
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Animal("A", 10);
Animal b = new Animal("B", 20);
if (a.compareTo(b) > 0) {
System.out.println("A가 나이가 더 많아요!");
} else if (a.compareTo(b) < 0) {
System.out.println("B가 나이가 더 많아요!");
} else {
System.out.println("A와 B의 나이가 같아요!");
}
}
}
위 코드에서 a.compareTo(b)를 통해서 a(자기 자신)객체와 b(파라미터)객체의 나이를 비교한다. 이때 a가 10살, b가 20살 이므로 compareTo 메서드의 비교는 음수가 리턴되게 된다. 따라서 "B가 나이가 더 많아요!"가 콘솔에 출력된다.
Comparator 인터페이스
자기 자신과는 무관하게 두 개의 파라미터를 비교한다. compare 메서드를 오버라이딩해서 구현한다.
import java.io.*;
import java.util.*;
class Animal implements Comparator<Animal> {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compare(Animal o1, Animal o2) {
return o1.age - o2.age;
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Animal("A", 10);
Animal b = new Animal("B", 20);
if (a.compare(a, b) > 0) {
System.out.println("A가 나이가 더 많아요!");
} else if (a.compare(a, b) < 0) {
System.out.println("B가 나이가 더 많아요!");
} else {
System.out.println("A와 B의 나이가 같아요!");
}
}
}
위 코드에서 a.compare(a, b)를 통해서 a(자기 자신)와 무관하게 a(파라미터)객체와 b(파라미터)객체의 나이를 비교한다. 이때 a가 10살, b가 20살 이므로 compare 메서드의 비교는 음수가 리턴되게 된다. 따라서 "B가 나이가 더 많아요!"가 콘솔에 출력된다.
Collections.sort(), Arrays.sort()
public static <T extends Comparable<? super T>> void sort(List<T> list) -> Collections.sort()
public static <T> void sort(T[] a, Comparator<? super T> c) -> Arrays.sort()
Collections.sort()는 List<T>를 정렬하는 메서드이다. 그리고, T 클래스는 Comparable<T>를 구현해야 한다. 즉, 앞에서 설명했던 부분 처럼 compareTo 메서드를 오버라이딩 해야한다.
Arrays.sort()는 배열을 정렬하는 메서드이다. 아래의 코드는 Collections.sort()를 기준으로 설명하지만, Arrays.sort()도 동일하게 사용하면 된다.
* Collections.sort()와, Arrays.sort()의 시간 복잡도 비교
public static void sort(int[] a) {
DualPivotQuicksort.sort(a, 0, 0, a.length);
}
// Arrays.sort()는 DualPivotQuickSort 방식으로 정렬한다.
// 최고(Best) : O(NlogN)
// 평균(Average) : O(NlogN)
// 최악(Worst) : O(N^2)
// Collections.sort는 TimSort 방식으로 정렬한다.
// 최고(Best) : O(N)
// 평균(Average) : O(NlogN)
// 최악(Worst) : O(NlogN)
-> 시간 복잡도를 생각하면 Collections.sort()를 사용하는 것이 더 좋다.
import java.io.*;
import java.util.*;
class Animal implements Comparable<Animal> {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Animal o) {
return this.age - o.age;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Animal("A", 10);
Animal b = new Animal("B", 20);
Animal c = new Animal("C", 15);
List<Animal> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
Collections.sort(list);
System.out.println(list);
}
}
위 코드는 Animal의 compareTo 메서드를 나이순으로 정렬하도록 구현했다. 따라서 A, B, C 순서로 리스트에 입력되었지만, Collections.sort 연산에 의해서 A, C, B 순서로 리스트에 저장된 순서가 바뀌게 된다.
import java.io.*;
import java.util.*;
class Animal {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Animal("A", 10);
Animal b = new Animal("B", 20);
Animal c = new Animal("C", 15);
List<Animal> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
Collections.sort(list, (o1, o2) -> o1.age - o2.age);
System.out.println(list);
}
}
위 코드처럼 Animal 클래스에 Comparable<Animal>을 구현하지 않고, 람다를 통해서 정렬할 수도 있다.
import java.io.*;
import java.util.*;
class Animal {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Animal("A", 10);
Animal b = new Animal("B", 20);
Animal c = new Animal("C", 15);
List<Animal> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
Collections.sort(list, new Comparator<Animal>() {
@Override
public int compare(Animal o1, Animal o2) {
return o1.age - o2.age;
}
});
System.out.println(list);
}
}
또는, 위 코드처럼 Comparator<Animal>을 생성해서 compare 메서드를 오버라이딩해서 비교할 수도 있다.