공부/Java

[Java]Comparable 과 Comparator 인터페이스

leejinwoo1126 2021. 9. 30. 23:51
반응형

 

요약

- Comparable 인터페이스 : 객체 스스로에게 부여하는 한 가지 기본 정렬 규칙을 설정하는 것이 목적

- Comparator 인터페이스 : 기본 정렬 규칙과 다른 정렬 기준을 지정하고 싶을 때 사용

 

아래 익명 함수 정의하는 방식은 구식이기 때문에, 람다 표현식과 Method Reference 사용 방법 익히는 것을 권장합니다

  • Comparable 와 Comparator 는 둘 다 인터페이스로, 정렬 기준을 구현하기 위해 사용됨
    • Comparable 인터페이스는 compareTo() 메서드를 override 해서 구현
    • 보통 정렬이 필요한 클래스에 Comparable 인터페이스 구현
  • Comparator 인터페이스는 compare() 메서드를 override 해서 구현
    • 보통 별도 (클래스) 정의해서 구현하며, 동일 객체에 다양한 정렬 기준을 가진 클래스를 작성 가능
    • 클래스에 interface Comparable method구현하여 정렬기준을 잡더라도 Comparator가 우선 순위를 가지게 됨

예시

- wrapper 클래스 계열의 경우 Arrays.sort() , Collections.sort() 사용시 기본적으로 오름차순 정렬이 됨

- 사용자 정의 클래스의 경우 객체 정렬의 기준이 필요하므로 Comparable 인터페이스를 상속받아 정렬 기준 정의해야 함

int[] nums = {3,4,5,7,1,2};
Arrays.sort(nums);
for(int i : nums) System.out.print(i + " ");    // 1 2 3 4 5 7

ArrayList<String> arr = new ArrayList<>(Arrays.asList("마","다","가","나"));   
Collections.sort(arr);
for(String j : arr) System.out.print(j + " "); // 가 나 다 마

 

Student.java

public class Student implements Comparable<Student>{ 

    private int no;       //번호
    private String name;//이름
    private int score;  //점수

    // getter , setter, constructor 생략 

    @Override
    public int compareTo(Student o) { // 정렬 기준 만드는 함수
        return this.no - o.getNo(); // 번호 오름차순으로 정렬 ( 내림차순의 경우 o.getNo() - this.no 또는 함수 활용)   
    }

}

 

ComparableTest.java

public static void main(String[] args) {
      ArrayList<Student> list = new ArrayList<>();
      list.add(new Student(2, "홍길동", 96));
      list.add(new Student(1, "이순신", 89));
      list.add(new Student(3, "김철수", 50));
      list.add(new Student(4, "최영희", 70));

      // Student 클래스에서 구현한 Comparable 인터페이스 함수(compareTo()) 기준으로 정렬함
      // no에 대해 오름차순 정렬 정의해둔 상태
      Collections.sort(list); 

      for(Student obj : list){
          System.out.println(obj.getNo() + ", "+ obj.getName()+ ", " + obj.getScore());
      }
}

 

번호 - 오름차순 정렬 결과

 1, 이순신, 89
 2, 홍길동, 96
 3, 김철수, 50
 4, 최영희, 70

 

score(점수)순으로 정렬하고 싶은 경우

- Comparator가 Comparable보다 우선순위를 가지므로 아래 성적 기준을 실행함
- 정렬 방법은 Collectiosn.sort() 함수 매개변수에 Comparator 정의 내려주면됨 
- 오름차순으로 정렬할 경우

Collections.sort(list, new Comparator<Student>(){
    @Override // 오버라이드된 해당 정렬 함수를 사용자 정의 내려줌 
    public int compare(Student o1, Student o2) { 
        if(o1.getScore() > o2.getScore()){ 
            return 1 ; 
        } else if(o1.getScore() < o2.getScore()){
            return -1; 
        } else{ 
            return 0; 
        } 
    } 
 });
// 결과 출력
for(Student obj : list){
  System.out.println(obj.getNo() + ", "+ obj.getName()+ ", " + obj.getScore());
}

 

score(점수) 오름차순 정렬 결과

3, 김철수, 50
4, 최영희, 70
1, 이순신, 89
2, 홍길동, 96

 

점수 내림차순 정렬할 경우

Collections.sort(list, new Comparator<Student>(){
    @Override // 오버라이드된 해당 정렬 함수를 사용자 정의 내려줌 
    public int compare(Student o1, Student o2) { 
        if(o1.getScore() > o2.getScore()){
            return -1 ;     // 여기 바뀜
        }else if(o1.getScore() < o2.getScore()){
            return 1;        // 여기 바뀜
        }else{
            return 0;
        }
    } 
 });
 
// 결과 출력
for(Student obj : list){
  System.out.println(obj.getNo() + ", "+ obj.getName()+ ", " + obj.getScore());
}

 

score(점수) 내림차순 정렬 결과

2, 홍길동, 96
1, 이순신, 89
4, 최영희, 70
3, 김철수, 50

참고

https://cwondev.tistory.com/15
https://www.daleseo.com/java-comparable-comparator/
https://ifuwanna.tistory.com/232
https://hee96-story.tistory.com/75

반응형