Comparator와 Comparable
두가지 모두 두개의 객체를 비교하기 위한 인터페이스 이다.
Comparator의 compare() 메서드는 두 매개변수 객체를 비교하고,
Comparable의 compareTo() 메서드는 자기자신과 매개변수 객체를 비교한다.
객체 o1, o2가 있을 때 , compare(o1, o2) / o1.compareTo(o2) 가 가능할 것이다.
이때, return 값에 따라 o1과 o2의 위치가 결정된다.
- return 1 (양수) : 위치를 변경하지 않음. 즉, o1이 o2보다 앞쪽에 위치하도록 결정
- return -1(음수) : 위치를 변경함. 즉, o1이 o2의 뒤에 위치하도록 결정
- return 0 : return1과 비슷하거나 같음. 위치를 변경하지 않음
public interface Comparator<T> {
int compare(T o1, T o2);
}
public interface Comparable<T> {
public int compareTo(T o);
}
Comparator 구현
MyMember라는 객체를 정렬하고자 할때, 정렬 조건을 설정하기위해 Comparator 클래스를 구현한다.
- o1의 나이 > o2의 나이 인 경우 - return 1 : o1이 o2의 앞쪽에 위치. 즉 o1 - o2 순서.
- o1의 나이 == o2의 나이 인 경우 - return 0 : 순서를 변경하지 않음. 즉 list에 추가된 순서대로 위치.
- o1의 나이 < o2의 나이 인 경우 - return -1 : 순서를 변경하여 o2가 o1보다 앞쪽에 위치하도록 변경. 즉 o2 - o1 순서.
위에서 설명했듯이 꼭 1, -1이 아니고 양수, 음수이면 되기 때문에 if,else if, else 문 대신에 ' return o1-o2; ' 를 해도 된다.
Collections.sort(list, new Comparator<MyMember>() {
@Override
public int compare(MyMember o1, MyMember o2) {
if(o1.age>o2.age)return 1;
else if(o1.age==o2.age)return 0;
else return -1;
}
});
람다식 사용 (Comparator)
아래 두개의 결과는 같다.
Collections.sort(list, (o1, o2) -> {
if(o1.age>o2.age)return 1;
else if(o1.age==o2.age)return 0;
else return -1;
});
Collections.sort(list, (o1, o2) -> {
return o1.age-o2.age;
});
정렬 예제 1. Comparator 사용
- Comparator로 정렬 방법을 설정할 수 있다.
- 아래 예제의 경우에는 age, memberId 중 age가 작은 순서대로 정렬하였다.
- o1, o2가 주어졌을 때, compare(o1, o2)의 return에 따라 크기(순위)가 결정된다.
- return 1 : o1이 더 크다는 뜻 이므로, 정렬 시 o1이 o2의 뒤에 위치하게 된다.
- return -1 : o2가 더 크다는 뜻 이므로, 정렬 시 o2가 o1의 뒤에 위치하게 된다.
class MyMember{
String name;
int age;
int memberId;
public MyMember(String name, int age, int memberId) {
this.name = name;
this.age = age;
this.memberId = memberId;
}
}
public class Test{
public static void main(String[] args){
MyMember memberA = new MyMember("memberA",30,1001);
MyMember memberB = new MyMember("memberB",15,1010);
MyMember memberC = new MyMember("memberC",20,1005);
List<MyMember> list = new ArrayList<>();
list.add(memberA);
list.add(memberB);
list.add(memberC);
Collections.sort(list, new Comparator<MyMember>() {
@Override
public int compare(MyMember o1, MyMember o2) {
if(o1.age>o2.age)return 1;
else if(o1.age==o2.age)return 0;
else return -1;
}
});
System.out.println(list.get(0).name+" "+list.get(1).name+" "+list.get(2).name);
// memberB memberC memberA
}
}
만약 age가 큰 순서대로 정렬하고 싶다면, compare() 부분을 아래와 같이 변경하면 된다.
Collections.sort(list, new Comparator<MyMember>() {
@Override
public int compare(MyMember o1, MyMember o2) {
if(o2.age>o1.age)return 1;
else if(o1.age==o2.age)return 0;
else return -1;
}
});
정렬 예제 2. Comparable 사용
- 이번엔 정렬 대상이 되는 클래스에 직접 implements Comparable<>를 적용해보자.
- 이 경우에는 main에서 Collections.sort(list)를 했을 때, MyMember클래스 내부에서 이미 적용된 정렬 방식에 따라 정렬된다.
class MyMember implements Comparable<MyMember>{
String name;
int age;
int memberId = 1000;
public MyMember(String name, int age, int memberId) {
this.name = name;
this.age = age;
this.memberId = memberId;
}
@Override
public int compareTo(MyMember o) {
if(this.age>o.age)return 1;
else if(this.age==o.age)return 0;
else return -1;
}
}
public class Test{
public static void main(String[] args){
MyMember memberA = new MyMember("memberA",30,1001);
MyMember memberB = new MyMember("memberB",15,1010);
MyMember memberC = new MyMember("memberC",20,1005);
List<MyMember> list = new ArrayList<>();
list.add(memberA);
list.add(memberB);
list.add(memberC);
Collections.sort(list);
System.out.println(list.get(0).name+" "+list.get(1).name+" "+list.get(2).name);
// memberB memberC memberA
}
}
반응형
'JAVA & Spring' 카테고리의 다른 글
[JAVA] 문자열 다루기 String, StringBuilder, StringBuffer (0) | 2023.06.28 |
---|---|
[Java] Scanner, BufferedReader, BufferedWriter (0) | 2023.06.26 |
[JAVA] 배열의 길이 length에는 괄호()가 붙지 않고, 문자열의 길이 length()에는 괄호()가 붙는 이유 (0) | 2023.06.03 |
[JAVA] Math 클래스 (0) | 2023.06.02 |
[JAVA] format() 메서드 : 문자열 포맷 지정 / printf() (0) | 2023.06.01 |