Arrays.sort()
를 호출만 하면 컴퓨터가 알아서 배열을 정렬하는 것처럼 보이지만, 사실은 Character
클래스의 Comparable
의 구현에 의해 정렬되었던 것이다.
Comparator와 Comparable은 모두 인터페이스로 컬렉션을 정렬하는데 필요한 메서드를 정의하고 있다.
Comparable을 구현하고 있는 클래스들은 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스들, 주로 Integer와 같은 wrapper 클래스와 String, Date, File과 같은 것들이며 기본적으로 오름차순, 즉 작은 값에서부터 큰 값의 순서로 정렬되도록 구현되어 있다.
따라서 Comparable을 구현한 클래스는 정렬이 가능하다는 것을 의미한다.
public interface Comparator {
int compare(Object o1, Object o2);
boolean equals(Object obj);
}
public interface Comparable {
public int compareTo(Object o); // Natural Order
}
비교 대상이 같으면 0, 비교하는 값보다 작으면 음수, 크면 양수를 반환한다.
즉,
Comparable
은 자기 자신과 파라미터로 들어오는 객체를 비교하는 것이고,Comparator
는 자기 자신의 상태가 어떻던 상관없이 파라미터로 들어오는 두 객체를 비교하는 것이다. 즉, 본질적으로 비교한다는 것 자체는 같지만, 비교 대상이 다르다는 것이다.
/**
* 1. 작성자 : Dani
* 2. 작성일 : 12월 10일
* 3. Comparator 재정의 : 기본 정렬기준 외에 다른 기준으로 정렬하고자할 때 사용
*/
package Basics;
import java.util.Arrays;
import java.util.Comparator;
/**
* 내림차순으로 재정의 하기
*/
class DecendingOrder implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
int c = o1.compareTo(o2);
return c * -1;
}
}
public class ComparableEx1 {
public static void main(String[] args) {
String[] alphas = {"D", "a", "B", "C", "z"};
Arrays.sort(alphas, new DecendingOrder());
System.out.println(Arrays.toString(alphas));
/**
* 익명함수 형태로 사용해보기
*/
String[] alphas2 = {"D", "a", "B", "C", "z"};
Comparator<String> decendingOrders = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
Arrays.sort(alphas2, decendingOrders);
System.out.println(Arrays.toString(alphas2));
String[] alphas3 = {"D", "a", "B", "C", "z"};
Arrays.sort(alphas3, Comparator.reverseOrder()); // 미리 정의되어있는 메서드가 있음
System.out.println(Arrays.toString(alphas3));
}
}
[z, a, D, C, B]
[B, C, D, a, z]
[z, a, D, C, B]
/**
* 1. 작성자 : Dani
* 2. 작성일 : 12월 10일
* 3. 로또 게임 만들어보기
*/
package Basics;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
public class LottoEx1 {
public static void main(String[] args) {
HashSet<Integer> lotto = new HashSet<>(); // 중복되는 숫자 제거
while (lotto.size()<6){
int num = (int) (Math.random() * 45) + 1;
lotto.add(num);
}
Iterator<Integer> iterator = lotto.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
package Basics;
public class Book implements Comparable<Book>{
private String name;
private int price;
public Book(String name, int price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public int compareTo(Book book) {
return this.name.hashCode() - book.name.hashCode(); // 이름 순
}
}
/**
* 1. 작성자 : Dani
* 2. 작성일 : 12월 10일
* 3. TreeSet과 Comparator 재정의
*/
package Basics;
import java.util.*;
class Des implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2) * -1;
}
}
public class BookMain {
public static void main(String[] args) {
/**
* Book클래스 내부에 정렬 메서드가 재정의 되어 있음
*/
TreeSet<Book> set = new TreeSet<Book>();
set.add(new Book("작가6", 2000));
set.add(new Book("작가2", 5000));
set.add(new Book("작가4", 2000));
set.add(new Book("작가4", 2000));
set.add(new Book("작가1", 6000));
Iterator<Book> iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
/**
* 정렬 메서드를 추가함
*/
TreeSet<String> set1 = new TreeSet<String>(new Des());
set1.add("작가6");
set1.add("작가3");
set1.add("작가98");
set1.add("작가1");
Iterator<String> iterator1 = set1.iterator();
while (iterator1.hasNext()){
System.out.println(iterator1.next());
}
}
}
Book{name='작가1', price=6000}
Book{name='작가2', price=5000}
Book{name='작가4', price=2000}
Book{name='작가6', price=2000}
작가98
작가6
작가3
작가1