1. Comparator
Comparator를 사용하려면 Array나 List Collectons일때 가능하다. 정렬기준을 Arrays.sort()나 Collections.sort()에서 사용가능하다. 내가 정의한 정렬기준에 대해서 배열과 List Collection을 정렬할 수 있다. 다음에서 숫자 오름차순, 내림차순정렬, 문자열 정렬, 다중배열 정렬, 참조변수 정렬에 대해서 알아보자.
일단 정렬에 사용할 클래스타입 Person을 정의하고 시작해보도록 하자.
package Java10_collection;
public class Person {
private int no;
private String name;
private String hobby;
public Person(int no, String name, String hobby) {
setNo(no);
setName(name);
setHobby(hobby);
}
@Override
public String toString() {
return getNo()+" "+getName()+" "+getHobby();
}
//getter setter
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
2. Comparator 정의하기
Comparator<클래스타입> 클래스명 = new Comparator<클래스타입>()으로 정의하고 일반적으로 compare메소드를 오버라이드해서 사용한다. 클래스타입 비교대상 2개를 지역변수 o1,o2로 선언하고 return값으로 음수,0,양수를 반환하면서 정렬할 수 있다.
Comparator<Person>comp = new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
return 0;
}
};
이를 Collections.sort()에 대입해본다면
Collections.sort(list,comp);
한번에 사용한다면 이런 모양이 될 것이다.
Collections.sort(list,new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
//o1보다 o2의 넘버가 크다면
//no기준 오름차순 정렬
if(o1.getNo()<o2.getNo()) { //1,2,3
return -1;
}
else if(o1.getNo()>o2.getNo()){
return 1;
}
else {
return 0; }
}
});
만약에 제네릭이 Integer 데이터 타입이라면 단순히 o1<o2비교로 되겠지만, 매개변수가 참조변수이고 원하는 변수가 private접근제한자라면 getter를 통해서 호출해서 비교하면 된다. return 값이 음수라면 왼쪽으로 정렬될것이고(오름차순), 양수라면 오른쪽으로 정렬된다(내림차순). 이는 Integer.compare()메소드를 사용하면 더 편하게 구할 수 있다. 다중<String>배열이 입력되었을 때 이 메소드를 사용해서 오름차순해본다면
Arrays.sort(arr,new Comparator<Integer[]>() {
@Override
public int compare(Integer [] o1, Integer[] o2) {
return Integer.compare(o1[0] o2[0]);
}
});
이때 각 배열의 맨 처음을 비교해서 정렬하고자 한다면, 위와 같이 될 것이다. Integer.compare을 통해서 o1[0]과 o2[0]을 자연스럽게 비교해준다. 만약에 o1[0]이크고 o2[0]이 작다면 1이 반환된다(왼쪽이 클경우 오른쪽으로 보내줌). 반대의 경우라면 -1이 반환되서 그대로 작은 수가 왼쪽에 있게 된다.
3. Comparator 문자열 비교
Comparator 정수형 비교는 직관적이었으나 문자열비교는 compareTo()메소드를 이용해서 비교해주도록 한다. 원리는 아스키코드 값의 비교를 통해 왼쪽에 위치한 문자열의 아스키코드값이 더 크다면 >0이 될 것이고 작다면 <0이 될것이다. compareTo()를 통해 아스키코드값을 뺀 값이 반환되게 된다. 코드로 살펴보면,
//문자열 비교(Name을 기준으로 오름차순)
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
//왼쪽이 작은경우 ex) a와 c일때 아스키 코드 a-c는 마이너스이므로 왼쪽이 작다
if(o1.getName().compareTo(o2.getName())<0) {
return -1;
}
return 1;
}
});
아까 살펴봤던 Person클래스의 String name변수를 비교해서 사전순으로 정렬해보았다. compareTo()메소드를 이용해서 o1.getName()이 o2.getName()<0 -->즉 o1의 아스키코드값이 작을 때 (오른쪽의 String값이 더 클때) -1을 반환하므로 써 왼쪽으로 보내주는 오름차순 정렬을 수행하게 된다. 반대의 내림차순인 경우에는 retrun 1을 해주면 내림차순 정렬로 될것이다. 백준 문제를 통해서 Comparator를 활용해서 정렬을 해보도록 하자.
https://www.acmicpc.net/problem/10814
https://github.com/choipureum/Java_Basic-SW-