Comparable과 Comparator

OneTwoThree·2023년 9월 22일
0

자바

목록 보기
19/19

출처


Comparable과 Comparartor는 모두 인터페이스이다.
Comparable, Comparator를 사용하려면 인터페이스 내에 선언된 메소드를 구현해야 한다.

Comparable 인터페이스에는 CompareTo(T o) 메서드 하나가 선언되어 있다.
Comparator 인터페이스에서 우리가 실질적으로 구현해야 하는 것은
compare(T o1, T o2) 이다.

두 인터페이스의 역할은 객체를 비교할 수 있도록 만드는 것이다.

primitive type의 경우 (byte, int, double)등 부등호를 갖고 쉽게 두 변수를 비교할 수 있다.

반면에 객체는 사용자가 기준을 정해주지 않으면 비교할 수 없다.

Comparable과 Comparator의 차이는 Comparable의 CompareTo(T o)는 매개변수가 한개다. 따라서 자기 자신과 매개변수 객체를 비교한다.
반면 Comparator는 compare(T o1, T o2)로 두 매개변수 객체를 비교한다.

그리고 Comparable은 lang 패키지에 있어서 import 해줄 필요가 없다. Comparator는 util 패키지에 있어서 import를 해줘야 한다.

Comparable

클래스를 만들 때 Comparable<Type>을 implement 하게 하고 compareTo(Type o) 를 오버라이딩 해서 구현해주면 된다.
compareTo를 통해 클래스를 비교하게 된다.

compareTo(Student o)는 정수를 반환한다.
자기 자신을 기준으로 비교해야 한다.
즉 내가 더 크면 양수, 같으면 0, 작으면 음수를 반환한다.

	public int compareTo(Student o) {
 
		/*
		 * 만약 자신의 age가 o의 age보다 크다면 양수가 반환 될 것이고,
		 * 같다면 0을, 작다면 음수를 반환할 것이다.
		 */
		return this.age - o.age;
	}

이렇게 구현하면 세가지를 한번에 해결할 수 있다.
다만 이렇게 - 로 리턴하는 방식을 사용하면 overflow 가 발생할 수도 있다. 따라서 primitive type에 대해서는 <,>,==로 대소비교를 해주는 것이 안전하다.

Comparator

Comparator는 두 매개변수 객체를 비교한다.
Comparator도 마찬가지로 implement 하고 구현해서 사용하면 된다.

	public int compare(Student o1, Student o2) {
 
		/*
		 * 만약 o1의 classNumber가 o2의 classNumber보다 크다면 양수가 반환 될 것이고,
		 * 같다면 0을, 작다면 음수를 반환할 것이다.
		 */
		return o1.classNumber - o2.classNumber;
	}

Comparator를 사용하면 비교를 위해 객체를 하나 생성해야 한다는 단점이 있다.
이것을 해결하기 위해 익명 클래스를 활용할 수 있다.
익명 클래스는 이름이 정의되지 않은 객체이다.

익명 객체는 상속할 클래스나 인터페이스가 있어야 한다.

		// 익명 객체 구현방법 1
		Comparator<Student> comp1 = new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				return o1.classNumber - o2.classNumber;
			}
		};
	// 익명 객체 구현 2
	public static Comparator<Student> comp2 = new Comparator<Student>() {
		@Override
		public int compare(Student o1, Student o2) {
			return o1.classNumber - o2.classNumber;
		}
	};

이렇게 익명 객체로 구현하면 클래스 내에 compare을 구현할 필요가 없다. 익명객체를 가리키는 comp를 통해 comp.compare(b,c)와 같이 사용하면 된다.

정렬과의 관계

Java에서 정렬은 특별히 정의가 되어 있지 않은 한 오름차순을 기준으로 한다.
Arrays.sort(), Collections.sort() 모두 오름차순을 기준으로 한다.
compare이나 compareTo를 사용해 비교할 때

  • 음수가 나온다 : 두 원소의 위치를 바꾸지 않는다
  • 양수가 나온다 : 두 원소의 위치를 바꾼다

오름차순

	// 자기 자신의 value을 기준으로 파라미터 값과의 차이를 반환한다.
	@Override
	public int compareTo(MyInteger o) {
		return this.value - o.value;
	}

내림차순

// Comparable
public int compareTo(MyClass o) {
	return -(this.value - o.value);
}
 
// Comparator
public int compare(Myclass o1, MyClass o2) {
	return -(o1.value - o2.value);
}

익명 클래스로 Comparartor를 구현한 comp 클래스를 만들고
Arrays.sort(array,comp) 로 정렬 기준을 정할 수 있다.

0개의 댓글