Development Palette

Comparator / Comparable 본문

Java

Comparator / Comparable

징주 2021. 8. 22. 15:53

Comparable 인터페이스

public interface Comparable { 
	public int compareTo(Object o); 
}

 

  • Arrays.sort()는 Character클래스의 Comparable 인터페이스의 구현에 의해 정렬됨.
  • 디폴트로 오름차순 정렬
  • 비교 하는 값보다 작으면 음수, 크면 양수, 같으면 0 반환
  • 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스를 구현한다.
  • 주로 wrapper클래스 : Integer, String, Date, File...등
  • java.lang
 

Java Platform SE 8

 

docs.oracle.com

Comparable 인터페이스로 내가 원하는 참조형 타입을 비교하는 법

--> 제네릭 사용하여 implements 하기

Camparable 구현하기

public class Student implements Comparable<Student> { //제네릭으로 구현 
  int no, score; public Student(int no, int score) { 
      super(); this.no = no; this.score = score; 
  } 

  @Override //Camparable 오버라이딩 
  public int compareTo(Student o) { 
      return this.no-o.no; 
      //return (this.no < o.no ? -1 : (this.no == o.no ? 0 : 1)); 랑 같은 의미 
      //비교 하는 값보다 작으면 음수, 크면 양수, 같으면 0 반환 
  } 

  @Override public String toString() {
      return "Student \[no=" + no + ", score=" + score + "]"; 
  }
}

실행

    private static void print(Student[] arr) {
        for(Student student:arr) {
            System.out.println(student);
        }
    }

    public static void main(String[] args) {
        Student[] arr=new Student[] {new Student(1,10), new Student(3, 50), new Student(2, 80),
                new Student(4, 20)};
        System.out.println("*** 정렬 전 ***");
        print(arr);

        System.out.println("*** 오름차순(번호) ***");  
        Arrays.sort(arr);
        print(arr);

*** 정렬 전 ***
Student [no=1, score=10]
Student [no=3, score=50]
Student [no=2, score=80]
Student [no=4, score=20]
*** 오름차순(번호) ***
Student [no=1, score=10]
Student [no=2, score=80]
Student [no=3, score=50]
Student [no=4, score=20]


Comparator

public interface Comparator {
	int compare(Object o1, Object o2);
    boolean equals(Object obj);
}
  • comparable 처럼 두 객체를 비교하는 목적
  • 기본 정렬 기준 외에 다른 기준으로 정렬하고자 할 때 사용 (내림차순)
  • java.util 패키지
  • equals 메소드는 모든 클래스가 가지고 있는 공통 메소드이지만, Comparator를 구현하는 클래스는 오버라이딩이 필요할 수도 있다는 것을 알리기 위해 정의한 것일 뿐, 그냥 compare(Object o1, Object o2)만 구현하면 된다.

 

Student 클래스의 인스턴스를 Comparator로 구현해 정렬

예제 1

public class Student {
	int no, score;

	public Student(int no, int score) {
		super();
		this.no = no;
		this.score = score;
	}
	
	@Override
	public String toString() {
		return "Student [no=" + no + ", score=" + score + "]";
	}

}
public class S02_ComparableTest {
	
	private static class StudentComparator implements Comparator<Student>{
		@Override
		public int compare(Student o1, Student o2) {
			return o2.no - o1.no;
		}
	}
	
	private static void print(Student[] arr) {
		for(Student student:arr) {
			System.out.println(student);
		}
	}
	
	public static void main(String[] args) {
		Student[] arr=new Student[] {new Student(1,10), new Student(3, 50), new Student(2, 80),
				new Student(4, 20)};
		System.out.println("*** 정렬 전 ***");
		print(arr);
        
        	System.out.println("*** 내림차순(번호) ***");  
		Arrays.sort(arr, new StudentComparator());
		print(arr);
    }
}

*** 정렬 전 ***
Student [no=1, score=10]
Student [no=3, score=50]
Student [no=2, score=80]
Student [no=4, score=20]
*** 내림차순(번호) ***
Student [no=4, score=20]
Student [no=3, score=50]
Student [no=2, score=80]
Student [no=1, score=10]

예제 2

public class Student {
	int no, score;

	public Student(int no, int score) {
		super();
		this.no = no;
		this.score = score;
	}
	
	@Override
	public String toString() {
		return "Student [no=" + no + ", score=" + score + "]";
	}

}
import java.util.Arrays;
import java.util.Comparator;

public class S03_ComparatorTest {
	
	private static class MyComparator implements Comparator<int[]>{
		@Override
		public int compare(int[] o1, int[] o2) {
			int diff = o1[0]-o2[0];
            return diff!=0? diff : o2[1] - o1[1];
		}
	}
	
	public static void main(String[] args) {
		int[][] arr = new int[][] { { 1, 10 }, { 2, 50 }, { 2, 80 }, { 4, 10 }, { 1, 100 } };

		System.out.println("=========정렬 전=============");
		print(arr);
		System.out.println("=========정렬 후=============");
		Arrays.sort(arr, new MyComparator());
		print(arr);
	}

	private static void print(int[][] arr) {
		for (int[] a : arr) {
			System.out.println(Arrays.toString(a));
		}
	}
}

=========정렬 전=============
[1, 10]
[2, 50]
[2, 80]
[4, 10]
[1, 100]
=========정렬 후=============
[1, 100]
[1, 10]
[2, 80]
[2, 50]
[4, 10]

예제 3

방법 1. 내림차순 할 때 주의점 : Comparable 구현해주기

public class Student implements Comparable<Student> {
	int no, score;

	public Student(int no, int score) {
		super();
		this.no = no;
		this.score = score;
	}

	@Override
	public int compareTo(Student o) {
		return this.no-o.no;		
		//return (this.no < o.no ? -1 : (this.no == o.no ? 0 : 1)); 랑 같은 의미
		//비교 하는 값보다 작으면 음수, 크면 양수, 같으면 0 반환
	}
	
	@Override
	public String toString() {
		return "Student [no=" + no + ", score=" + score + "]";
	}

}
import java.util.Arrays;
import java.util.Comparator;

public class S04_ComparatorReverseTest {
	public static void main(String[] args) {
		Integer[] arr = new Integer[] { 4, 3, 7, 9, 10 };
		System.out.println("정렬 전 : " + Arrays.toString(arr));
		Arrays.sort(arr, Comparator.reverseOrder()); 
		System.out.println("정렬 후 : " + Arrays.toString(arr));
		
		String[] location = { "서울", "대전", "광주", "구미"};
		System.out.println("정렬 전 : " + Arrays.toString(location));
		Arrays.sort(location, Comparator.reverseOrder());
		System.out.println("정렬 후 : " + Arrays.toString(location));
		
		Student[] students = new Student[] { new Student(1, 10), new Student(3, 50), new Student(2, 80),
				new Student(4, 10) };
		System.out.println("=========정렬 전=============");
		for (Student student : students) {
			System.out.println(student);
		}
		//error ==> Student가 Compareable일때 가능함
		Arrays.sort(students, Comparator.reverseOrder());
		System.out.println("=========번호 내림차순=============");
		for (Student student : students) {
			System.out.println(student);
		}
	}
}

정렬 전 : [4, 3, 7, 9, 10]
정렬 후 : [10, 9, 7, 4, 3]
정렬 전 : [서울, 대전, 광주, 구미]
정렬 후 : [서울, 대전, 구미, 광주]
=========정렬 전=============
Student [no=1, score=10]
Student [no=3, score=50]
Student [no=2, score=80]
Student [no=4, score=10]
=========번호 내림차순=============
Student [no=4, score=10]
Student [no=3, score=50]
Student [no=2, score=80]
Student [no=1, score=10]

방법 2.

내림차순을 하기 위해서 compareTo()의 결과에 -1을 곱하거나, 비교하는 객체의 위치를 바꿔서 해도 된다.

주의 : compare() 매개변수가 Object타입이기 때문에 compareTo()를 바로 호출할 수 없으므로 먼저 Comparable로 형변환

class Descending implements Comparator {
	public int compare(Object o1, Object o2){
    	if( o1 instanceof Comparable && o2 instanceof Comparable){
			Comparable c1 = (Comparable) o1;
            Comparable c2 = (Comparable) o2;
            return c1.compareTo(c2) * -1;	//기본 정렬의 역으로 변경
            // 또는 return c2.compareTo(c1);
        }
        
        return -1;
    }
}

 

'Java' 카테고리의 다른 글

HashMap 정렬  (0) 2021.09.29
싱글톤패턴(Singleton Pattern)  (0) 2021.08.23
직렬화 Serializtion  (0) 2021.08.22
메모리  (0) 2021.08.08
변수  (0) 2021.08.05
Comments