
개요
Apex의 List 클래스에서 Comparator 인터페이스를 지원함에 따라 List의 sort()메서드를 내 입맛에 맞게 커스터마이징이 가능해졌다. 이를 통해 단순히 String이나 Integer같은 자료형 말고도, 복잡한 구성을 가지는 객체들의 리스트에서 내가 정렬 기준을 정해 sort()를 사용할 수 있게 되었다.
Comparator, 비교자 인터페이스 말고도 Comparable 인터페이스가 있어 개발자가 정의한 Apex class의 인스턴스끼리 비교가 가능하다. Comparable 인터페이스에 대한 내용은 다음글을 참고한다.
2024.05.24 - [Salesforce/Salesforce Dev] - Comparable Interface
Comparable Interface
개요Apex의 List 클래스는 Apex 코딩 시 정말 자주 사용하는 자료구조로써 많은 기능들이 내장되어 있어 이를 편리하게 사용할 수 있다. 그 중, List안에 들어있는 요소들을 오름차순으로 정렬하는
unknown-dev.tistory.com
바로 코드 예시를 통해 사용법을 알아보자.
Comparator 인터페이스 예시
이전의 Comparable 인터페이스 예시 코드와 동일하게 Dog 클래스가 아래와 같이 있다고 해보자.
당연하게도, 두 개체간 비교할 "기준"이 없으므로 맨 마지막의 dogs.sort()는 에러를 뿜어낸다.
class Dog {
public String name;
public Integer age;
public Boolean isAlive;
public Dog(String name, Integer age, Boolean isAlive) {
this.name = name;
this.age = age;
this.isAlive = isAlive;
}
}
List<Dog> dogs = new List<Dog>();
dogs.add(new Dog('Cola', 4, true));
dogs.add(new Dog('Absolute', 6, true));
dogs.add(new Dog('Zondo', 2, true));
dogs.sort();
Comparator 사용은 Comparable 사용법과는 많이 다르다. 비교할 대상 클래스에 직접 구현했던 Comparable 인터페이스와는 달리, Comparator는 별도의 비교자 클래스를 만들고 그 클래스로 하여금 구현하도록 한다.
무슨 말이냐면.. 아래 코드처럼 비교자 클래스들을 별도로 생성해야 한다는 것이다.
아래 예시는 name으로 정렬하기 위한 비교자 클래스와, age로 정렬하기 위한 비교자 클래스를 생성한 것이다.
이 비교자 클래스는 Comparator 인터페이스를 구현하며, compare() 메서드를 반드시 작성해줘야 한다.
//Dog를 Name으로 정렬하기 위한 정렬자
public class NameCompare implements Comparator<Dog> {
public Integer compare(Dog d1, Dog d2) {
if (d1?.name == null && d2?.name == null) {
return 0;
} else if (d1?.name == null) {
return -1;
} else if (d2?.name == null) {
return 1;
}
return d1.name.compareTo(d2.name);
}
}
//Dog를 age로 정렬하기 위한 정렬자
public class YearCompare implements Comparator<Dog> {
public Integer compare(Dog d1, Dog d2) {
// Guard against null operands for ‘<’ or ‘>’ operators because
// they will always return false and produce inconsistent sorting
Integer result;
if(d1?.age == null && d2?.age == null) {
result = 0;
} else if(d1?.age == null) {
result = -1;
} else if(d2?.age == null) {
result = 1;
} else if (d1.age < d2.age) {
result = -1;
} else if (d1.age > d2.age) {
result = 1;
} else {
result = 0;
}
return result;
}
compare()의 반환값은 Comparable 인터페이스의 compareTo() 메서드를 구현할 때와 동일하다.
첫번재 인자가 두번째 인자보다 큰것을 나타내려면 양수, 작음을 나타내려면 음수, 같음은 0이다.
Comparator 구현 클래스까지 만들었으면, 이제 실제 어떻게 사용하는지 살펴보자.
static void testCustomSortWithComparator() {
List<Dog> dogs = new List<Dog>();
dogs.add(new Dog('Cola', 4, true));
dogs.add(new Dog('Absolute', 6, true));
dogs.add(new Dog('Zondo', 2, true));
NameCompare nameCompare = new NameCompare();
dogs.sort(nameCompare);
}
비교자 클래스의 인스턴스를 하나 생성해준 후, List의 sort() 메서드를 호출할 때 인자로 던져주면 된다.
정리
List에서 Apex class 타입의 요소들을 정렬하는 방법이 두 가지가 있다.
- Comparable
- Comparator
필요에 따라 골라서 사용하면 되겠다. 그냥 빠르게 작성을 한다면 아무래도 첫번째 방법이 우위에 있다. 별도의 클래스를 만들지 않아도 되니 말이다. 하여 주로 JSON parser 등에 사용되는 Apex 클래스 하나를 정렬하고자 할때 주로 사용하면 편리할 것 같다. 그러나 만약 어떤 속성이 A 클래스에도 있고 B 클래스에도 있고 그 속성으로 A 클래스 타입의 List와 B 클래스 타입의 List 모두 정렬을 해야한다는 상황이면 두번째 방법이 더 유리하다고 생각한다.
'Salesforce > Salesforce Dev' 카테고리의 다른 글
| Invocable Apex Method (0) | 2024.05.27 |
|---|---|
| (Secure Apex) User Mode Database Operations (0) | 2024.05.27 |
| Comparable Interface (0) | 2024.05.24 |
| Apex Null Coalescing Operator (0) | 2024.05.12 |
| Apex Test Data Loading with csv (0) | 2024.04.16 |