알고리즘 공부를 하다가 우연히 Comparable과 Comparator의 글을 보게 되어서
공부한 내용을 포스팅한다.
자바 [JAVA] - Comparable 과 Comparator의 이해
익명객체 내용을 포함해서 굉장히 도움이 많이 됬다.
Comparable과 Comparator 전에 익명객체를 먼저 알아야 한다.
익명객체는 말그대로 이름을 가지지 않은 객체다.
일반적인 상속받은 클래스를 객체화 해서 사용하는 것과 비슷(?) 한 것 같음.
일반적인 상속을 활용한 코드
public class Anonymous { public static void main(String[] args) { Rectangle a = new Rectangle(); ChildRectangle child = new ChildRectangle(); System.out.println(a.get()); // 20 System.out.println(child.get()); // 10 * 20 * 40 } } class ChildRectangle extends Rectangle { int depth = 40; @Override int get() { return width * height * depth; } } class Rectangle { int width = 10; int height = 20; int get() { return height; } }
익명객체를 활용한 코드
public class Comparable_Test { public static void main(String[] args) { Student a = new Student(17 , 2); Student b = new Student(18 , 3); // comparable의 특징 // 자기 자신과 비교이므로 a와 b를 비교함. int isBig = a.compareTo(b); if(isBig > 0) { System.out.println("a객체가 b객체보다 큽니다."); } else if(isBig == 0) { System.out.println("두 객체의 크기가 같습니다."); } else { System.out.println("a객체가 b객체보다 작습니다."); } } } class Student implements Comparable<Student> { int age; int classNumber; Student(int age, int classNumber) { this.age = age; this.classNumber = classNumber; } @Override public int compareTo(Student o) { /* * 만약 자신의 age가 o의 age보다 크다면 양수가 반환 될 것이고, * 같다면 0을, 작다면 음수를 반환할 것이다. */ return this.age - o.age; } }
객체를 비교하기 위해 Comparable 또는 Comparator을 사용한다.
compare 혹은 compareTo를 사용하여 객체를 비교할 경우 음수가 나오면 두 원소의 위치를 바꾸지 않는다는 것이다.
Comparable 인터페이스 사용
import java.util.*; public class ArraysSort_Test { public static void main(String[] args) { MyInteger[] arr = new MyInteger[10]; // 객체 배열 초기화 (랜덤 값으로) for(int i = 0; i < 10; i++) { arr[i] = new MyInteger((int)(Math.random() * 100)); } // 정렬 전 System.out.print("정렬 전 : "); for(int i = 0; i < 10; i++) { System.out.print(arr[i].value + " "); } System.out.println(); Arrays.sort(arr); // 정렬 후 System.out.print("정렬 후 : "); for(int i = 0; i < 10; i++) { System.out.print(arr[i].value + " "); } System.out.println(); } } class MyInteger implements Comparable<MyInteger> { int value; public MyInteger(int value) { this.value = value; } @Override public int compareTo(MyInteger o) { return this.value - o.value; } }
여기서 compareTo의 return 값을 바꾸거나 주석처리 후 돌려보면 오류가 난다.
정렬에 대한 규칙을 정의하지 않았기 때문이다.
Array.sort(array)가 아닌 Array.sort(array, comp)도 가능하다.
import java.util.*; import java.util.Comparator; public class ArraySort_Test { public static void main(String[] args) { MyInteger[] arr = new MyInteger[10]; // 객체 배열 초기화 (랜덤 값으로) for(int i=0; i<10; i++) { arr[i] = new MyInteger((int)(Math.random() * 100)); } System.out.print("정렬 전 : "); for(int i=0; i<10; i++) { System.out.print(arr[i].value + " "); } System.out.println(); //MyInteger에 대한 Comparator를 구현한 익명객체를 넘겨줌 Arrays.sort(arr, comp); System.out.print("정렬 후 : "); for(int i=0; i<10; i++) { System.out.print(arr[i].value + " "); } } static Comparator<MyInteger> comp = new Comparator<MyInteger>() { @Override public int compare(MyInteger o1, MyInteger o2) { return o1.value - o2.value; } }; } class MyInteger { int value; public MyInteger(int value) { this.value = value; } }
알고리즘 문제 푸는 것도 중요하지만 역시 이런 기본기도 중요하다고 항상 생각한다.
어떤 원리를 통해서 작동하는지, 또는 어떻게 응용할 수 있는지를 아는 것도 중요하니까.
다음은 익명객체와 compare와 compareTo를 통한 내림차순을 포스팅 할 예정.
하루에 하나는 너무 감질맛 나네요 더 올려주세요