Comparable과 Comparator
Updated:
Comparable과 Comparator
- Comparable 정렬 수행 시 기본적으로 적용되는 정렬 기준이 되는 메서드를 정의하는 인터페이스.(compareTo을 통해 구현)
- Comparator은 정렬 가능한 클래스들의 기본 정렬 기준과 다르게 정렬하고 싶을때 사용하는 인터페이스(comapre를 통해 구현)
Interface Comparable
- 정렬 수행 시 기본적으로 적용되는 정렬 기준이 되는 메서드를 정의하는 인터페이스
- package : java.lang.Comparable
- java에서 제공되는 정렬이 가능한 클래스들은 모두 Comparable 인터페이스를 구현하고 있으며, 정렬 시에 이에 맞게 정렬이 수행된다.
- Ex)Integer, Double 클래스 : 오름차순 정렬 & Ex)String 클래스 : 사전순 정렬
- 구현방법
- 정렬할 객체에 Comparable interface를 implements한 후, compareTo() 메서드를 오버라이드하여 구현한다.
- 자신과 인자로 전달 받는 타 원소와 비교하여 정수 리턴
- compareTo() 메서드 작성법
- 현재 객체 < 파라미터로 넘어온 객체 : 음수 리턴
- 현재 객체 == 파라미터로 넘어온 객체 : 0리턴
- 현재 객체 > 파라미터로 넘어온 객체 : 양수 리턴
- 음수 또는 0이면 객체의 자리가 그대로유지되며, 양수인 경우에 두 객체의 자리가 바뀐다.
- 사용방법
- Arrays.sort(array) : 배열 정렬인 경우
- Collections.sort(list) : List Collection정렬인 경우
class Student implements Comparable<Studeng>{
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;
}
}
Interface Comparator
- 정렬 가능한 클래스(Comparable 인터페이스를 구현한 클래스)들의 기본 정렬 기준과 다르게 정렬하고 싶을 때 사용하는 인터페이스
- package: java.util.Comparator
- 주로 익명 클래스로 사용된다.
- 기본적인 정렬방법인 오름차순 정렬을 내림차순으로 정렬할때 많이 사용한다.
- Comparator interface를 implements한 후 , compare()메서드를 오버라이드한 myComparator class를 작성한다.
- 비교대상의 두 원소가 아닌 별도의 도우미 역할.
- compare() 메서드 작성법
- 첫번째 파라미터로 넘어온 객체 < 두번째 파라미터로 넘어온 객체 : 음수 리턴
- 첫번째 파라미터로 넘어온 객체 == 두번째 파라미터로 넘어온 객체 : 0리턴
- 첫번째 파라미터로 넘어온 객체 > 두번째 파라미터로 넘어온 객체 : 양수 리턴
- 음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우에는 두 객체의 자리가 변경된다.
- 사용방법
- Arrays.sort(array, myComparator)
- Collections.sort(array, myComparator)
- Arrays.sort(), Collections.sort() 메서드는 두번째 인자로 Comparator interface를 받을 수 있다.
class Student{
int no, score;
public Studeng(int no, int score){
super();
this.no = no;
this.score = score;
}
}
class StudentComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2){
return o1.no - o2.no;
}
}
예시 코드
Comparable interface를 이용한 java 객체를 정렬
package comparetest;
public class Car implements Comparable<Car>{
private int carNum;
private String carName;
private String maker;
public Car(int carNum, String carName, String maker) {
super();
this.carNum = carNum;
this.carName = carName;
this.maker = maker;
}
public int getCarNum() {
return carNum;
}
public void setCarNum(int carNum) {
this.carNum = carNum;
}
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
public String getMaker() {
return maker;
}
public void setMaker(String maker) {
this.maker = maker;
}
@Override
public String toString() {
return "Car [carNum=" + carNum + ", carName=" + carName + ", maker=" + maker + "]";
}
//차번호로 compare하여 정렬하기
@Override
public int compareTo(Car car) {
if(this.carNum > car.carNum) { //내림차순
// if(this.carNum < car.carNum) {
//오름차순
return -1;
}else if(this.carNum == car.carNum) {
return 0;
}else {
return 1;
}
}
//차이름으로 compare하여 정렬하기
@Override
public int compareTo(Car car) {
if(this.carName.compareTo(car.carName) > 0) {
//return 1;//오름차순
return -1;//내림차순
}else if(this.carName.compareTo(car.carName) < 0) {
//return -1;//오름차순
return 1; //내림차순
}else {
return 0;
}
//return this.carName.compareTo(car.carName);
}
}
Comparable test와 comparator 익명 클래스 사용
public class CarCompareTest {
public static void main(String[] args) {
Car car = new Car(2460,"SonataB","HD");
Car car1 = new Car(2450,"KB","KIA");
Car car2 = new Car(2440,"QM6","SS");
Car car3 = new Car(2430,"SonatA","HD");
Car car4 = new Car(2420,"XM3","SS");
Car car5 = new Car(2410,"K5","KIA");
Car car6 = new Car(2960,"GENESIS","HD");
Car car7 = new Car(2360,"Avante","HD");
Car car8 = new Car(2160,"SM6","SS");
List<Car> list = new ArrayList<Car>();
list.add(car1);
list.add(car2);
list.add(car3);
list.add(car4);
list.add(car5);
list.add(car6);
list.add(car7);
list.add(car8);
view(list);
System.out.println(">>>>>>>>>>>>>>>차번호로 정렬 후 결과");
Collections.sort(list);
view(list);
System.out.println(">>>>>>>>>>>>>>>차이름로 정렬 후 결과");
Comparator<Car> carNameCompare = new Comparator<Car>() {
@Override
public int compare(Car c1, Car c2) {
if(c1.getCarName().compareTo(c2.getCarName()) > 0) {
return 1;//오름차순
//return -1;//내림차순
}else if(c1.getCarName().compareTo(c2.getCarName()) < 0) {
return -1;//오름차순
//return 1; //내림차순
}else {
return 0;
}
//return this.carName.compareTo(car.carName);
}};
Collections.sort(list, carNameCompare);
view(list);
Comparator<Car> carMakerCompare = new Comparator<Car>() {
@Override
public int compare(Car c1, Car c2) {
if(c1.getMaker().compareTo(c2.getMaker()) > 0) {
return 1;//오름차순
//return -1;//내림차순
}else if(c1.getMaker().compareTo(c2.getMaker()) < 0) {
return -1;//오름차순
//return 1; //내림차순
}else {
return 0;
}
//return this.carName.compareTo(car.carName);
}};
System.out.println(">>>>>>>>>>>>>>>제조사로 정렬 후 결과");
Collections.sort(list, carMakerCompare);
view(list);
}
private static void view(List<Car> list) {
System.out.println("차번호\t차이름\t제조사");
for (Car car : list) {
System.out.println(car);
}
}
}
stringCompare 예시
public class StringCompareTest {
public static void main(String[] args) {
String[] word = {"boy", "Cat", "Lion", "dog", "elephant", "i", "dragon", "Any", "giraffe", "animal", "Dogcat", "girl"};
List<String> list = Arrays.asList(word);
System.out.println("1.List : " + list);
Collections.sort(list);
System.out.println("2.List(sort) : " + list); //string의 compareto는 사전순 정렬이 default
//문자열 길이를 기준으로 오름차순 정렬 후 사전 순 정렬
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
int len1 = s1.length();
int len2 = s2.length();
if(len1 != len2) {
return len1 - len2;
}
return s1.compareTo(s2);
}
});
System.out.println("3.List(sort) : " + list);
}
}
References
https://gmlwjd9405.github.io/2018/09/06/java-comparable-and-comparator.html
Leave a comment