본문 바로가기
나만의 정리

[Java]Comparable, Comparator 정리(+ 자료형)

by 코리늬 2018. 11. 19.

Comparable, Comparator 정리(+ 자료형)

자바는 primitive type기본형 타입과 reference type 참조형 타입이 있다.

Java Data Type
ㄴ Primitive Type
  ㄴ Boolean Type(boolean)
  ㄴ Numeric Type
      ㄴ Integral Type
          ㄴ Integer Type(short, int, long)
          ㄴ Floating Point Type(float, double)
      ㄴ Character Type(char)
ㄴ Reference Type
  ㄴ Class Type
  ㄴ Interface Type
  ㄴ Array Type
  ㄴ Enum Type
  ㄴ etc.

기본 자료형
  • 기본 자료형은 반드시 사용하기 전에 선언 되어야 한다.

  • OS에 따라 자료형의 길이가 변하지 않는다.

  • null 값을 가질 수 없다.

참조 자료형
  • java.lang.Object를 상속 받으면 참조형이 된다.

  • 선언한 자료형이 기본형이 아닌 경우 참조형이 된다고 보면 된다.

  • 클래스형, 인터페이스형, 배열형이 있다.

자바에서 정렬을 사용하는 방법은 두 가지가 있다.

  • 배열의 경우 Arrays.sort(arr)

  • 리스트의 경우 Collections.sort(list)

우리가 위의 방법으로 기본형 타입이나, 참조형 타입의 String을 자동정렬을 할 수 있는 이유는

자바에서 기본 제공하는 Object의 경우 Comparable 인터페이스를 구현하고 있기 때문이다.

그래서 다양한 조건을 기반으로 정렬하는 경우 반드시 Comparable 인터페이스를 구현해줘야 한다.

테스트를 위해 Book 객체를 하나 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Book {
  private String name;
  private int price;
  public Book(String name, int price){
      this.name = name;
      this.price = price;
  }
  public int getPrice() {
      return price;
  }
  public void setPrice(int price) {
      this.price = price;
  }
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
}
cs

그리고 메인에는 임의로 객체를 담고 정렬을 해준다.

1
2
3
4
5
6
7
Book[] books = new Book[3];
books[0= new Book("a",300);
books[1= new Book("b",200);
books[2= new Book("c",100);
Arrays.sort(books);
cs

하지만 이와 같이 정렬을 하면

Exception in thread "main" java.lang.ClassCastException: practice.Book cannot be cast to java.base/java.lang.Comparable

에러가 난다.

그 이유는 비교 대상이 없기 때문이다. 비교 대상의 기준이 필요하다.

Book 객체에 Comparable을 implements 해준 후 compareTo 메소드를 구현해 주어야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Book implements Comparable<Book>{
  private String name;
  private int price;
  public Book(String name, int price){
      this.name = name;
      this.price = price;
  }
  public int getPrice() {
      return price;
  }
  public void setPrice(int price) {
      this.price = price;
  }
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  public String toString(){
      return "book : " + this.name +"   "+ "price : "+this.price;
  }
  @Override
  public int compareTo(Book o) {
      //오름차순
      return this.price - o.price;
      //내림차순
      //o.price - this.price;
  }
}
cs

이렇게 해줌으로써

book : c price : 100 book : b price : 200 book : a price : 300 결과가 출력되는 것을 볼 수 있다.

그렇다면 name을 기준으로 정렬하고 싶을 때는 어떻게 해야할까?

이때 사용하는게 Comparator 인터페이스이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.util.Arrays;
import java.util.Comparator;
public class BookTest {
  public static void main(String[] args) {
      Book[] books = new Book[3];
      books[0= new Book("a",300);
      books[1= new Book("b",200);
      books[2= new Book("c",100);
      Arrays.sort(books);
      for(Book book : books){
          System.out.println(book);
      }
      Arrays.sort(books, (o1, o2) -> o1.getName().compareTo(o2.getName()));
      /*Arrays.sort(books, new Comparator<Book>() {
          @Override
          public int compare(Book o1, Book o2) {
              return o1.getName().compareTo(o2.getName());
          }
      });*/
      for(Book book : books){
          System.out.println(book);
      }
      //System.out.println(Arrays.toString(books));
  }
}
cs

sort() 메소드의 2번째 인자에 Comparator를 익명클래스로 전달해 정렬기준을 재정의 한다.

Comparable은 객체의 기본 정렬기준을 구현하는데 사용하고

Comparator는 그 외의 사용자 기준 정렬기준이 필요할 때 구현해서 사용하면 된다.


댓글