보통 primitive 값을 정렬 할 경우, Object 클래스의 equals() 메소드를 따로 정의하지 않아도 비교가 가능하고, Comparable 인터페이스의 compareTo() 메소드를 구현하지 않아도 Arrays.sort() 메소드를 통해 오름차순 정렬이 쉽게 가능합니다.
그러나 대부분의 문제는 인스턴스를 비교하고 정렬할 때 발생합니다.
❗️ 정수 대신 인스턴스를 비교, 정렬 할 경우 ❗️
인스턴스는 정렬하는데 기준이 필요하기 때문에
정렬할 인스턴스의 클래스에 Comparable 인터페이스를 구현 해주고 해당 인터페이스의 메소드인 compareTo() 메소드를 원하는 정렬 기준으로 오버라이딩 해주어야 합니다.
compareTo(Object o)
return 값
- 양수 (비교한 두 수 위치 변경)
- 음수 (위치 변경 x)
- 0 (위치 변경 X)예시
@Override public int compareTo(Object o) { // 나이의 오름차순 정렬 Person p = (Person) o; return this.age - p.age; }
비교의 경우는 정렬할 때 구현한 compareTo() 메소드를 기준으로 return 값이 0 일 경우 해당 인덱스를 반환해 줍니다.
class Person implements Comparable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
나이 오름차순 정렬
class Person implements Comparable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Object o) { // 나이의 오름차순 정렬
Person p = (Person) o;
return this.age - p.age;
}
}
public static void main(String[] args) {
Person[] ar = new Person[10];
ar[0] = new Person("Lee", 29);
ar[1] = new Person("Lee", 29);
ar[2] = new Person("Soo", 37);
ar[3] = new Person("So", 36);
ar[4] = new Person("So", 99);
ar[5] = new Person("So", 23);
ar[6] = new Person("Abc", 37);
ar[7] = new Person("aBC", 38);
ar[8] = new Person("asdfg", 17);
ar[9] = new Person("sssssss", 47);
// 정렬
Arrays.sort(ar);
// 정렬된 배열 출력
for (Person p : ar) {
System.out.println(p);
}
// 탐색 결과 출력
System.out.println();
System.out.println("idx: " + Arrays.binarySearch(ar, new Person("NULL", 29)));
}
[출력 결과]:
asdfg: 17
So: 23
Lee: 29
Lee: 29
So: 36
Soo: 37
Abc: 37
aBC: 38
sssssss: 47
So: 99
idx: 2
❗️이름이 다르더라도 나이만 같다면 이진 탐색의 결과로 인덱스가 반환됩니다.
(나이만 같아도 compareTo()의 return 값이 0이되기 때문에 인스터스를 찾았다고 판단)
이름 길이순 + 알파벳 순 정렬, 이름이 같다면 나이 오름차순 정렬
static class Person implements Comparable {
.
.
.
@Override
public int compareTo(Object o) {
Person p = (Person) o;
// 이름 길이 오름차순 정렬
if (this.name.length() > p.name.length()) {
return 1;
} else if (this.name.length() < p.name.length()) {
return -1;
// 이름길이가 같다면
} else {
for (int i = 0; i < this.name.length(); i++) {
if ((int) this.name.toLowerCase().charAt(i) != (int) p.name.toLowerCase()
.charAt(i)) {
// 알파벳순 정렬
return (int) this.name.toLowerCase().charAt(i) - (int) p.name.toLowerCase()
.charAt(i);
}
}
// 이름이 같다면 나이순 정렬
return this.age - p.age;
}
}
public static void main(String[] args) {
Person[] ar = new Person[10];
ar[0] = new Person("Lee", 29);
ar[1] = new Person("Lee", 29);
ar[2] = new Person("Soo", 37);
ar[3] = new Person("So", 36);
ar[4] = new Person("So", 99);
ar[5] = new Person("So", 23);
ar[6] = new Person("Abc", 37);
ar[7] = new Person("aBC", 38);
ar[8] = new Person("asdfg", 17);
ar[9] = new Person("sssssss", 47);
// 정렬
Arrays.sort(ar);
// 정렬된 배열 출력
for (Person p : ar) {
System.out.println(p);
}
// 탐색 결과 출력
System.out.println();
System.out.println("idx: " + Arrays.binarySearch(ar, new Person("NULL", 99)));
System.out.println("idx: " + Arrays.binarySearch(ar, new Person("So", 99)));
}
[출력 결과]:
So: 23
So: 36
So: 99
Abc: 37
aBC: 38
Lee: 29
Lee: 29
Soo: 37
asdfg: 17
sssssss: 47
idx: -9 // 탐색에 실패하여 음수 반환
idx: 2
❗️ 이름이 일치하고, 나이까지 같아야 compareTo() 가 0을 반환하기에 둘 다 일치해야 해당 인덱스를 반환합니다.