본문 바로가기
공부하기!/JAVA

Comparator VS Comparable

by 갈매기^0^ 2024. 1. 2.

Why?

일반적으로 자바에서의 정렬은 Integer, String등과 같은 primitive Type에 대한 비교를 지원해주지만

자바에서 사람과 같은 객체를 정렬하려면 어떻게 해야할까? 에서 나온것이 Comparator와 Comparable이다.

What?

  • 둘다 정렬을 사용하기 위한 인터페이스로 각각의 구현해야하는 메서드가 존재한다.
  • 자바는 오름차순이 기본이기에 - 연산을 통해 선행과 후행을 비교시 양수가 나올경우 위치를 바꾸고 음수가 나올 시 가만히 놔둔다.
/*
 [오름차순]
 */
public int compareTo(MyClass o) {
	return this.value - o.value;
}
public int compare(Myclass o1, MyClass o2) {
	return o1.value - o2.value;	
    return (o1.value - o2.value) * -1;
}
  • 내림차순의 경우 연산된 결과에 -1을 곱해주자!

Comparable

  • compareTo(T o) 메서드를 오버라이드 할 수 있다.
  • 매개변수가 하나인것에서 확인 할 수 있듯이 자기자신과 다른 객체의 매개변수를 비교한다.
  • 주소 객체의 기본 정렬을 바꾸고 싶을때 정의

Comparator

  • compare(T o1, T o2)
  • 매개변수가 2개인것으로 서로다른 객체 2개를 비교한다.
  • 익명 객체를 통해 재정의를 여러번하여 특별한 시점에 특정 정렬을 진행하기를 원할 때 사용가능

How?

Comparable

class Student implements Comparable<Student> {
 
	/*
내용
*/
	
	@Override
	public int compareTo(Student o) {
		/*
		 * 비교 구현
		 */
	}
}
  • 자기자신과 다른 Student의 매개변수를 비교한다.
  • 음수, 양수, 0을 표현 가능하긴 하지만 오버플로우에 유의하자
    • 대소 비교를 통한 조건절을 사용하는것이 안전할 수 있다.

Comparator

import java.util.Comparator;	// import 필요
class Student implements Comparator<Student> {
 /*
내용
*/
	
	@Override
	public int compare(Student o1, Student o2) {
    
		// o1의 학급이 o2의 학급보다 크다면 양수
		if(o1.classNumber > o2.classNumber) {
			return 1;
		}
		// o1의 학급이 o2의 학급과 같다면 0
		else if(o1.classNumber == o2.classNumber) {
			return 0;
		}
		// o1의 학급이 o2의 학급보다 작다면 음수
		else {
			return -1;
		}
	}
}
  • 자기자신이 아닌 2개의 객체를 비교할 수 있다.
  • 2개의 객체를 비교하기위한 객체가 필요하다 → 익명객체의 등장!
// 나이 대소 비교 익명 객체
	public static Comparator<Student> comp2 = new Comparator<Student>() {
		@Override
		public int compare(Student o1, Student o2) {
			return o1.age - o2.age;
		}
	};
}

//자바 8 이후
public static Comparator<Student> comp2 = Comparator.comparingInt(student -> student.age);

public static Comparator<Student> comp2 = (o1, o2) -> o1.age - o2.age;
 
class Student {
 
	int age;			// 나이
	int classNumber;	// 학급
	
	Student(int age, int classNumber) {
		this.age = age;
		this.classNumber = classNumber;
	}
	
}
Arrays.sort(inventory, new Comparator() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return Integer.compare(o1.getWeight(), o2.getWeight());
            }
        });
출처: <https://inpa.tistory.com/entry/☕-람다식-리팩토링-Comparator> [Inpa Dev 👨‍💻:티스토리]
  • 와 같이 sort함수에 Compatator를 직접 주입하여 표현하는 방식도 존재