오늘의 취준/오늘의 공부

[Java] comparable 인터페이스

gogoem 2023. 8. 12. 20:32
728x90

Comparable 인터페이스는 비교를 위한 인터페이스이다.

객체 정렬에 사용되는 compareTo 메소드를 선언하고 있고, 이 메소드를 재정의(Override)하여 boolean을 제외한 클래스의 인스턴스를 정렬할 수 있다.

 

 

부등호를 통해 쉽게 비교할 수 있는 int, string 등의 자료형과 달리 비교해야 하는 대상이 객체라면?

x, y 좌표를 가진 객체의 배열을 정렬하는 경우를 생각해 보자.

class Point{
  public int x, y;
  Point(int x, int y){
    this.x = x;
    this.y = y;
  }

public class Main{
	public static void main(String[] args){
        ArrayList<Point> arr = new ArrayList<>();
        arr.add(new Point(0, 5));
        arr.add(new Point(3, 5));
        arr.add(new Point(3, 4));
        arr.add(new Point(4, 2));
        arr.add(new Point(6, 1));
  }
}

x값을 기준으로 오름차순 정렬을 하되, x값이 같을 경우 y값을 기준으로 객체를 비교해 배열을 정렬해야 한다.

반복문을 이용해 코드를 짜는 경우 각 객체를 비교해야 하기 때문에 코드가 길고 복잡해진다.

더 많은 속성을 가진 객체라면 더욱 복잡해질 것이다.

 

 

 

 

이런 경우에 Comparable 인터페이스의 compareTo 메소드를 사용하면 간단히 객체 배열을 정렬할 수 있다.

 

 

 

먼저 객체를 비교하는 코드를 작성했다.

class Point implements Comparable<Point>{
  public int x, y;
  Point(int x, int y){
    this.x = x;
    this.y = y;
  }

  @Override
  public int compareTo(Point o) {
    if(this.x == o.x){         //객체의 x와 인자 o의 x값이 같을 때,
      return this.y - o.y;     //y값 비교 > 객체의 y값이 작으면 음수, o의 값이 작으면 양수 반환
    }else return this.x - o.x; //객체의 x값이 다를 때, > 객체의 x값이 작으면 음수, o의 값이 작으면 양수 반환
  }  
}

public class Main {
  public static void main(String[] args){
        Point a = new Point(0, 5);
        Point b = new Point(3, 5);
        
        int com = a.compareTo(b);
        
        if(com = 0) System.out.println("a와 b는 같음");
        else if(com > 0) System.out.println("a가 b보다 큼");
        else System.out.println("b가 a보다 큼");
  }
}

CompareTo의 반환값은 세 가지로 나눌 수 있다.

양수, 0, 음수이다.

양수일 경우 현재 객체가 비교 객체(인수로 들어가는 o)보다 크다는 뜻이고, 

0일 경우는 두 값이 동일하다는 뜻이고,

음수일 경우 현재 객체가 비교 객체보다 작다는 뜻이다.

그래서 위의 if else 문을 이용해 a와 b를 비교해 출력할 수 있다.

 

 

 

 

이제 Collections를 사용해 객체의 배열을 정렬할 수 있다.

  • Collections.sort(list);
import java.util.ArrayList;
import java.util.Collections;

class Point implements Comparable<Point>{
  public int x, y;
  Point(int x, int y){
    this.x = x;
    this.y = y;
  }

  @Override
  public int compareTo(Point o) {
    if(this.x == o.x){         //객체의 x와 인자 o의 x값이 같을 때,
      return this.y - o.y;     //y값 비교 > 객체의 y값이 작으면 음수, o의 값이 작으면 양수 반환
    }else return this.x - o.x; //객체의 x값이 다를 때, > 객체의 x값이 작으면 음수, o의 값이 작으면 양수 반환
  }  
}

public class Main {
  public static void main(String[] args){
    ArrayList<Point> arr = new ArrayList<>();
    arr.add(new Point(0, 5));
    arr.add(new Point(3, 5));
    arr.add(new Point(3, 4));
    arr.add(new Point(4, 2));
    arr.add(new Point(6, 1));
    
    Collections.sort(arr);

    for(Point o : arr){
      System.out.println(o.x+" "+o.y);
    }
  }
}

Collections 는 compareTo에서 설정한 조건에 따라 ArrayList 배열을 정렬해준다. (array 는 Array.sort 사용)

위의 코드를 실행하면 설정한 조건대로 출력이 잘 나오는 것을 확인할 수 있다.

0 5
3 4
3 5
4 2
6 1