본문 바로가기
개발공부/Java

[Java] - Compartor와 Comparable

by dding-g 2020. 5. 17.

📌 Java - Comparator, Comparable

프로그래머스의 알고리즘 문제 가장 큰 수 를 풀다가 Comparator와 Comparable을 만나게 되어 한번 정리해보고 넘어가도록 하겠다.

포스팅 내용은 해당 블로그 를 바탕으로 내가 이해한 내용을 풀어서 작성했다.

🙄 Sort는 어떻게 이루어 질까

Arrays.sort()함수를 사용하면 우리는 쉽게 배열 안에 있는 숫자, 문자열 들을 정렬 할 수 있다.

보통 내림차순으로 정렬이 이루어 지는데, 정렬 기준을 바꿀 수 있도록 해주는게 Comparator, Comparable이라고 볼 수 있다.

Java 에서 지원하는 정렬이 가능한 클래스들은 모두 Comparable을 상속 받고 있다.

그렇다면 ComparatorComparable의 차이는 무엇일까?

📕 ComparatorComparable 의 차이?

위에서 말햇듯이 Java에서 지원하는 정렬이 가능한 클래스들은 모두 Comparable을 상속 받고 있다.

이로 미루어 보았을때

  • 클래스 자체가 정렬을 지원하는 기능을 포함하면 Comparable을.
  • 따로 정렬 기준만 만들고 싶다면 Comparator 를 쓰면 된다?

라고 생각 된다.

맞는 말이다. 맞말추

정의를 살펴보면

Comparable
정렬 수행 시 기본적으로 적용되는 정렬 기준 을 위한 메서드를 정의하는 Interface

Comparator
정렬 가능한 클래스(Comparable 인터페이스를 구현한 클래스)들의 기존의 정렬 기준과 다르게 정렬 하고 싶을때 사용하는 Interface

두 클래스 모두 Interface이다. 단,

  • 기본이 되는 정렬 기준 = Comparable
  • 기존의 정렬 기준과 다르게 정렬하고 싶을때 = Comparator

이런 차이점이 있다.

🥕 어떻게 사용할까?

이해를 돕기위해 LoL의 챔피언 이름과 레벨이 저장된 Champion 클래스를 한번 만들어 보도록 하겠다.

🔧 Comparable 사용법

//Comparable Class
public class Champion implements Comparable<Champion>{
    String champName;
    int champLevel;

    public Champion(String champName, int chapLevel) {
        this.champName = champName;
        this.champLevel = chapLevel;
    }

    public String getChampName() {
        return champName;
    }

    public void setChampName(String champName) {
        this.champName = champName;
    }

    public int getChampLevel() {
        return champLevel;
    }

    public void setChampLevel(int champLevel) {
        this.champLevel = champLevel;
    }

    @Override
    public int compareTo(Champion champion) {
        //String에서 compareTo 를 사용하게 되면,
        //왼쪽에 있는 값(champName)이 오른쪽의 값(getChampName())보다 크면
        //1 return
        //작으면 -1 return, 같으면 0을 return 한다.
        return champName.compareTo(champion.getChampName()); 
    }
}

Champion.compareTo() 메서드를 한번 보자. String.compareTo() 의 경우는 주석에 설명을 간단히 적어 두었다.

Override한 Comparable.compareTo() 의 경우, 오름차순으로 정렬한다면 1, 내림차순으로 정렬하려면 -1 의 return 값을 가져야 한다.

🔧 Main에서는 어떻게 호출할까?

public static void main(String[] args) {
        Champion champion[] = {new Champion("masterE", 7), 
                               new Champion("Garen", 10), 
                               new Champion("Oren", 9)};

        Arrays.sort(champion);

        for(Champion c : champion){
            System.out.println(c.getChampName() + " : " + c.getChampLevel());
        }
    }

Name과 Level을 무작위로 가지고 있는 champion[] 을 만들어 보았다. 이걸 이름 기준으로 내림차순으로 정렬하려면 String의 경우는 그냥 Arrays.sort 함수를 사용하면 되지만, Object의 경우 따로 Comparable 인터페이스가 필요하다. 따라서 Champion 클래스를 이름순으로 정렬하려면 위와 같이 코드를 작성하면 된다.

🔧 Comparator 사용법

public static void main(String[] args) {
        Champion champion[] = {new Champion("masterE", 7), 
                               new Champion("Garen", 10), 
                               new Champion("Oren", 9)};

        Arrays.sort(champion, new Comparator<Champion>() {
            @Override
            public int compare(Champion champion1, Champion champion2) {
                if(champion1.getChampLevel() > champion2.getChampLevel()){
                    return 1;
                }else if(champion1.getChampLevel() < champion2.getChampLevel()){
                    return -1;
                }else {
                    return 0;
                }
            }
        });

        for(Champion c : champion){
            System.out.println(c.getChampName() + " : " + c.getChampLevel());
        }
    }

이처럼 Arrays.sort 의 매개변수로 Comparator를 만들어서 넘겨주는 형식으로 구현한다.

이제 정렬할때 정말 유용하게 사용할 수 있을 것이다.