JAVA

[JAVA] 자바 객체 리스트(List) 정렬하기 (오름, 내림차순)

딘딘은딘딘 2023. 9. 11. 15:33
반응형

자바에는 Arrays.sort 등 다양한 방식으로 리스트를 정렬할 수 있다.

이 포스팅은 배열을 간단하게 오름차순, 내림차순으로 정렬하는 방법을 보여준다.


먼저 테스트를 위해 클래스를 만들고 데이터를 정의한다.

 

1. 오름차순 정렬

 

Collections.sort(godList);

for(God g : godList) {
    System.out.println(g);
}

위와 같이 코드를 실행하면 아래와 같이 출력된다

godList의 경우 List<God> 타입이다.

List<Integer> 타입이라면 값이 명확하게 정수형이기 때문에 오름차순으로 정렬이 되었을 것이다.

그러나 God는 객체이기 때문에 어떤 값을 기준으로 정렬을 하는지 알 수 없어 정렬이 진행되지 않았다.

 

Collections의 sort 메서드를 보면 파라미터로 List와 Comparator 함수형 인터페이스를 받을 수 있다.

이 함수형 인터페이스를 사용하면 정렬 조건을 내가 원하는 기준에 맞춰 사용할 수 있다.

 

Comparator<God> godComparator = Comparator.comparing(God::getPrice);

godList.sort(godComparator);

// Collections.sort(godList, godComparator);

- Collections.sort 는 메서드 내부에서 list.sort를 실행하기 때문에 godList.sort()로 더 간결하게 사용가능하다.

 

Comparator인터페이스의 comparing를 사용한 뒤 가격을 기준으로 오름차순 정렬하도록 동작을 정의한다.

(간결한 표현을 위해 메서드 참조를 사용)

 

 

Comparator의 comparing은 함수형 인터페이스 Comparator을 리턴하며 파라미터로 Function을 받는다.

따라서 람다 또는 메서드 참조를 이용해 값을 전달해주면 Comparator을 리턴받을 수 있다.

 

위 코드를 실행하면 아래와 같이 출력된다.

가격을 기준으로 오름차순 정렬 되었다.

 

추가로 위 코드는 더 간결하게 만들 수 있다.

godList.sort(Comparator.comparing(God::getPrice));

 

2. 내림차순 정렬 (역정렬)

이번엔 내림차순 정렬이다.

코드는 크게 바뀌는 부분이 없다.

 

Comparator<God> godComparator = Comparator.comparing(God::getPrice).reversed();

godList.sort(godComparator);

Comparator.comparing을 하는 부분에 reversed() 만 추가해주면 된다.

가격으로 정렬한 후 다시 내림차순으로 정렬한다.

 

 

 

** 번외로 객체가 아닌 List<Integer> 타입인 경우 내림차순 방법이다.

List<Integer> list = Arrays.asList(1,6,2,9,7,3,5,11);
list.sort(Comparator.reverseOrder());	// 내림차순

// list.sort(Comparator.naturalOrder()); // 오름차순
System.out.println(list);

// [11, 9, 7, 6, 5, 3, 2, 1]

list.sort의 경우 파라미터로 Comparator을 받는다 

Comparator.reverseOrder()은 파라미터를 받지 않지만,

역으로 정렬 하는 메서드가 정의된 Comaprator을 반환한다.

따라서 간단한 역정렬을 하고자 하는 경우 위와 같이 사용해도 된다.

 

3. 두 개 이상의 기준을 가진 정렬

두 개 이상의 기준을 가진 정렬을 하기 위해서는 thenComparing()을 사용하면 된다.

 

Comparator<God> godComparator = Comparator
                .comparing(God::getPrice)
                .reversed()
                .thenComparing(God::getGodCd);

godList.sort(godComparator);

위의 코드를 실행하면

 

아래와 같이 가격을 기준으로 내림차순 정렬 후

중복된 값이 있는 경우 GodCd를 기준으로 다시 오름차순 정렬을 진행해준다.

 

 


* 정리

- 객체를 다양한 방식으로 Collections.sort 하기 위해서는 함수형 인터페이스 Comparator를 타입으로 가지는 변수를 생성 해야한다.

- 람다를 활용하면 다양한 방식의 정렬 조건을 만들어 낼 수 있다.

 

 


추가

업무를 진행하다 객체 안의 객체가 있고 그 객체 안의 정수로 역순 정렬을 해야 하는 상황이 생겼다.

위의 예제에는 해당 케이스가 없어 다음에 참고하기 위해 아래에 추가했다.

// 객체 -> 객체 -> 정수의 정렬 방식
Comparator<Dish> reverseCompare = Comparator.comparing(v -> v.getGod().getPrice());
Comparator<Dish> comp = Collections.reverseOrder(reverseCompare);

// 위의 두 Comparator 필드를 스트림의 파라미터로 아래와 같이 주었다.
List<Dish> sorted = dishList.stream()
        .filter(Dish::isVegetarian)
        .sorted(Collections.reverseOrder(Comparator.comparing(v -> v.getGod().getPrice())))
        .toList();
반응형