9) 컬렉션 프레임워크4 - 정렬

dev-mage·2022년 11월 25일
0

Hello Java World!

목록 보기
28/32
post-thumbnail

Comparable과 Comparator로 컬렉션 정렬

Comparable과 Comparator

Comparable과 Comparator 모두 컬렉션을 정렬하는데 필요한 메서드를 정의하고 있는 인터페이스이다.

  • Comparable
    • 기본 정렬 기준을 구현하는데 사용.

    • Comparable을 구현하는 클래스들: 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스들(wrapper, String, Date, File 클래스 등). ⇒ 정렬이 가능함을 의미.

    • 기본적으로 오름차순으로 정렬되도록 구현되어 있음.

    • java.lang 패키지 소속.

    • 멤버로 오직 compareTo()만 가짐.

      public interface Comparable<T> {
      		public int compareTo(T o); // 객체 자신(this)과 o를 비교
      }
    • compareTo()의 반환값은 int이지만 실제로는 비교하는 두 객체가 같으면 0, 비교하는 값보다 작으면 음수, 크면 양수를 반환하도록 구현해야 함.

    • 예)

      public final class Integer extends Number implements Comparable<Integer> {
      		...
      		public int compareTo(Integer anotherInteger) {
      		    return compare(this.value, anotherInteger.value);
      		}
      		public static int compare(int x, int y) {
      		    return (x < y) ? -1 : ((x == y) ? 0 : 1);
      		}
      		...
      }
  • Comparator
    • 기본 정렬 기준 외에 다른 기준으로 정렬하고자 할 때 사용.

    • java.util 패키지 소속.

      public interface Comparator<T> {
      		int compare(T o1, T o2); // o1과 o2를 비교
      		boolean equals(Object obj);
      		...
      }
    • compareTo()와 마찬가지로 객체를 비교해서 음수, 0, 양수 중의 하나를 반환하도록 구현.

    • equals()는 오버라이딩 할 수 있지만 구현하지 않아도 무방.

    • 예)

      public class Arrays {
      		...
      		static final class NaturalOrder implements Comparator<Object> {
      		    public int compare(Object first, Object second) {
      		        return ((Comparable<Object>)first).compareTo(second);
      		    }
      		    ...
      		}
      		...
      }

Arrays.sort()

Arrays.sort()는 배열 정렬을 위한 메서드이다. Comparator를 지정해주지 않으면 저장하는 객체(Comparable을 구현한 클래스의 객체)에 구현된 내용에 따라 정렬된다.

String의 Comparable 구현은 문자열이 사전 순(오름차순)으로 정렬되도록 작성되어 있다(공백 → 숫자 → 대문자 → 소문자와 같이 문자의 유니코드 순서가 작은 값부터 큰 값으로 정렬).

public static void main(String[] args) {
    String[] arr = {"cake", "banana", "oreo", "apple", "app1e", "0re0"};
    Arrays.sort(arr); // [0re0, app1e, apple, banana, cake, oreo]
}

만약 문자열의 내림차순으로 정렬하고 싶다면 다음과 같이 Comparator를 구현하면 된다.

public static void main(String[] args) {
    String[] arr = {"cake", "banana", "oreo", "apple", "app1e", "0re0"};
    Arrays.sort(arr, new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
            if (o1 instanceof String && o2 instanceof String)
                return ((String) o2).compareTo((String) o1);
            return 0;
        }
    }); // [oreo, cake, banana, apple, app1e, 0re0]
}

사용자 정의 객체 정렬

만약 사용자가 정의한 객체를 정렬하려면 어떻게 해야할까? 앞서 언급한 것처럼 비교할 수 있는 객체는 Comparable을 구현해야 한다. 따라서 사용자 정의 객체에 Comparable을 구현하고 compareTo()를 오버라이딩 하면 된다. 아래 예제는 메뉴 가격이 적은 순서대로 정렬되도록 구현하였다.

public class Menu implements Comparable<Menu> {
    private String menuName;
    private int price;
    public Menu(String menuName) {
        this.menuName = menuName;
    }
    public Menu(String menuName, int price) {
        this.menuName = menuName;
        this.price = price;
    }
    public String getMenuName() {
        return menuName;
    }
    public int getPrice() {
        return price;
    }
    @Override
    public String toString() {
        return "<" + menuName + ": " + price + ">";
    }
    @Override
    public int compareTo(Menu menu) {
        return this.getPrice() - menu.getPrice();
    }
}
public static void main(String[] args) {
    Menu[] menus = {
            new Menu("coffee", 3500),
            new Menu("tea", 3000),
            new Menu("ade", 4500),
    };
    System.out.println(Arrays.toString(menus));
		// 실행 결과
		// [<coffee: 3500>, <tea: 3000>, <ade: 4500>]

		Arrays.sort(menus);
    System.out.println(Arrays.toString(menus));

		// 실행 결과
		// [<tea: 3000>, <coffee: 3500>, <ade: 4500>]
}

Reference

  • 자바의 정석 CHAPTER 11

0개의 댓글