본문으로 바로가기
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



자바의 객체 비교 Comparable와 Comparator


Array에 특정 문자 또는 특정 숫자의 값이 있다면..?

String[] fruits = {"grape", "fig", "berry", "cherry ","banana", "watermelon", "melon", "apple", "Orange", "kiwi", "mango", "pineapple"}; String[] names = {"김건모", "박서준", "이지은", "이효리", "임윤아", "이상순", "박보검", "정혜미", "마동석", "원빈" }; Arrays.sort(fruits); Arrays.sort(names); for(int i = 0; i < fruits.length; i++) {     System.out.print(fruits[i] + " "); } System.out.println(); for(int i = 0; i < names.length; i++) {     System.out.print(names[i] + " "); }

결과 값으로 아래와 같이 나옴을 알 수있다.

Orange apple banana berry cherry  fig grape kiwi mango melon pineapple watermelon 

김건모 마동석 박보검 박서준 원빈 이상순 이지은 이효리 임윤아 정혜미 

간단히 Arrays.sort() 메소드로 정렬이 되는 것을 알 수 있다.


객체 배열을 Sort하게 된다면 ?  설명하기 위해 먼저 클래스를 선언했다. 과일은 이름과 가격으로 했다.

class Fruit {
    private String name;
    private int price;
    
    public Fruit(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

        Fruit[] fruits = new Fruit[6];
        fruits[0] = new Fruit("grape", 10);
        fruits[1] = new Fruit("banana", 3);
        fruits[2] = new Fruit("apple", 5);
        fruits[3] = new Fruit("kiwi", 12);
        fruits[4] = new Fruit("mango", 14);
        fruits[5] = new Fruit("pineapple", 20);
        
        Arrays.sort(fruits);
        
        for(int i = 0; i < fruits.length; i++) {
            System.out.println(fruits[i].getName() + " ");
        }


결과 값으로 에러가 발생한다.

"main" java.lang.ClassCastException: test11.Fruit cannot be cast to java.lang.Comparable 가 발생한다.


우리가 의도했던 정렬이 일어나지 않는다.

우리가 또한 객체로 정렬을 하게 될경우 정렬은 가격이될까, 문자가 될지 알 수 없다.


그래서 Comparable을 이용하여 정렬이 될 특정 필드를 선택하여 compareTo 메소드를 구현하여야 한다.

아래 compareTo 메소드를 재정의하였는데 이름이아닌 가격순으로 비교하게끔 코드를 작성하였다.

class ComparableFruit implements Comparable<ComparableFruit> { private String name; private int price; public ComparableFruit(String name, int price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public int compareTo(ComparableFruit compareFruit) { //this가 먼저 앞에 있으면 ASC 비교할 대상이 먼저 앞에 잇으면 DESC

//return this.price - compareFruit.price; return compareFruit.price - this.price; } }


과일이름, 그리고 가격을 임의로 작성하여 Arrays.sort를 실행하면

        ComparableFruit[] fruits = new ComparableFruit[6];
        fruits[0] = new ComparableFruit("grape", 10);
        fruits[1] = new ComparableFruit("banana", 3);
        fruits[2] = new ComparableFruit("apple", 5);
        fruits[3] = new ComparableFruit("kiwi", 12);
        fruits[4] = new ComparableFruit("mango", 14);
        fruits[5] = new ComparableFruit("pineapple", 20);
        
        Arrays.sort(fruits);
        
        for(int i = 0; i < fruits.length; i++) {
            System.out.println(fruits[i].getName() + " ");
        }

결과 값으로 아래와 같이 나올 수 있다.

pineapple mango kiwi grape apple banana 


만약 가격이 아니라 이름순으로 한다면 .? 그리고 가격도 별도의 할인율, 주간별 평균 값을 정해서 정렬을 해야한다면 어떻게 해야할까

그럴경우에 Comparator 인터페이스를 사용하면 된다. sort 메소드의 인자로 Comparator이 들어감을 알 수 있고, Comparator을 인자로 전달하면서 compare 메소드를 재정의 해야 한다.

        Fruit[] fruits = new Fruit[6];
        fruits[0] = new Fruit("grape", 10);
        fruits[1] = new Fruit("banana", 3);
        fruits[2] = new Fruit("apple", 5);
        fruits[3] = new Fruit("kiwi", 12);
        fruits[4] = new Fruit("mango", 14);
        fruits[5] = new Fruit("pineapple", 20);
        
        for(int i = 0; i < fruits.length; i++) {
            System.out.print(fruits[i].getName() + " ");
        }
        
        System.out.println();
        
        Arrays.sort(fruits, new Comparator<Fruit>() {
            @Override
            public int compare(Fruit o1, Fruit o2) {
                String o1Name = o1.getName().toUpperCase();
                String o2Name = o2.getName().toUpperCase();
                
                return o1Name.compareTo(o2Name);
            }
        });
        
        for(int i = 0; i < fruits.length; i++) {
            System.out.print(fruits[i].getName() + " ");
        }

결과 값으로 아래와 같이 나옴을 알 수 있다.

grape banana apple kiwi mango pineapple 

apple banana grape kiwi mango pineapple


Comparator은 Array뿐만 아니라 Collection 즉 리스트 같은 자료구조를 사용하여 정렬할 때도 사용할 수 있다.