반응형
객체를 ordering 하는 방법에 대해 알아본다.
Comparable interface
- 객체의 natural ordering 에 대해 정의할 수 있음
- 클래스 안에서 클래스끼리 비교할 때 override해두면 Collections.sort, Arrays.sort 등에서 사용됨
- 하나뿐인 아래 함수를 상속받고 구현하면 됨, 구현해야지만 사용할 수 있음(not functional interface)
public int compareTo(T o);
- 해당 함수로 현재 객체(this)와 다른 객체(o)를 비교할 수 있으며 반환 값은 아래와 같음
- this < o : -1 정방향
- this == o : 0
- this > o : 1 역방향
- 참고로 String 객체는 해당 interface의 함수를 이미 구현하고 있어서 별도의 설정을 하지 않아도 알파벳 순 정렬을 할 수 있다.
import java.util.*;
@Getter
@ToString
@AllArgsConstructor
public class Person implements Comparable<Person> { ///
private String name;
private int age;
@Override
public int compareTo(Person other) { ///
return Integer.compare(this.age, other.age); // Natural order by age
}
// Main method for testing
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
// Sort using the natural order defined by Comparable
// 안줘도 자동으로 있는거 사용
Collections.sort(people);
System.out.println("Sorted by age (natural order): " + people);
}
}
Comparator Interface
- Comparator is intended to be used for defining external comparison logic rather than internal natural ordering. However, you can create a Comparator for Person as a separate class, an inner class, or even as a static field in the Person class to provide custom sorting criteria.
- 객체 자체의 natural ordering 이 없거나, 좀 더 복잡한 정렬 방법이 있을 경우 사용(flexibility)
- 아래 함수를 상속받고 구현하면 됨(functional interface) ; 람다로 사용가능
int compare(T o1, T o2);
- int를 반환하도록 되어있는데, 비교 값은 아래와 같다.
- 앞 < 뒤 : -1 정방향
- 앞 == 뒤 : 0
- 앞 > 뒤 : 1 역방햐
- String 객체에 역시 이미 정의 되어 있다.
기본함수
- Comparator<T> reversed():
- Returns a comparator that reverses the order of this comparator.
- Comparator<T> thenComparing(Comparator<? super T> other):
- Returns a comparator that first compares using this comparator, and if the comparison is equal, uses the provided comparator. 앞에 비교한 결과가 같으면 추가 사용!
import java.util.*;
@Getter
@ToString
@AllArgsConstructor
public class Person { //여기서 comparator implement못하고 별도의 클래스로 빼야 함
private String name;
private int age;
// Main method for testing
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
// Sort by name
// 별도로 만들어서 사용 , 람다 사용가능
Comparator<Person> nameComparator = Comparator.comparing(Person::getName);
Collections.sort(people, nameComparator);
System.out.println("Sorted by name: " + people);
// Sort by age in reverse order
Comparator<Person> ageComparator = Comparator.comparingInt(Person::getAge).reversed();
Collections.sort(people, ageComparator);
System.out.println("Sorted by age (reverse order): " + people);
}
}
//or 아래처럼 함수로 빼고 new AgeComparator() 삽입
// Comparator for sorting by age
public static class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return Integer.compare(p1.getAge(), p2.getAge());
}
}
어떤 것을 사용해야 하나
The Comparable interface is a good choice to use for defining the default ordering, or in other words, if it’s the main way of comparing objects.
기본적으로는 Comparable 을 사용하고 아래와 같은 경우 Comparator을 사용
- 파일이 수정 불가하여 interface를 구현할 수 없는 경우 Comparator 사용
- 비교 로직을 분리해서 관리해야하는 경우 Comparator 사용
- 비교 전략이 다양해서 Comparable 로 부족할 경우 Comparator 사용
참고
728x90
반응형
'개발 > java' 카테고리의 다른 글
불변객체 만들기 ImmutableCollections.class (0) | 2024.09.14 |
---|---|
[java] try with resources; close (1) | 2024.05.09 |
[java] 멀티 스레드 동시성 관련 (0) | 2024.05.08 |
[mysql] LocalDateTime.toLocalDate().atTime(LocalTime.MAX) 시간 반올림 이슈 (0) | 2024.02.16 |
[java] LocalDateTime, ZonedDateTime, OffsetDateTime (0) | 2024.02.14 |