리스트 정렬 방법에 대해 간단히 알아 보겠습니다.
예제에서 사용할 Book 클래스
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import java.time.LocalDateTime;
@AllArgsConstructor
@Getter
@Builder
@ToString
public class Book {
private Integer id;
private String title;
private LocalDateTime createdDate;
}
Book 객체 생성하는 함수입니다.
private Book makeBook(int id, int day) {
return Book.builder()
.id(id)
.createdDate(LocalDateTime.of(2022, 5, day, 10, 0))
.build();
}
id와 day를 파라미터로 받아 Book 객체를 생성합니다.
리스트 정렬을 하기 위해 stream을 생성하고, sorted 함수를 사용했습니다.
조건1개를 오름차순으로 정렬하는 예제
@Test
public void 조건1개_오름차순_정렬() {
// given
List<Book> books = new ArrayList<>();
books.add(makeBook(1, 7));
books.add(makeBook(2, 5));
books.add(makeBook(3, 9));
books.add(makeBook(4, 10));
books.add(makeBook(5, 4));
// when
List<Book> result = books.stream()
.sorted(Comparator.comparing(Book::getCreatedDate))
.collect(Collectors.toList());
log.debug("{}", result);
// then
assertThat(result.get(0).getId()).isEqualTo(5);
}
Comparator 인터페이스를 사용하면 기본적인 정렬은 쉽게 할 수 있습니다.
조건1개를 내림차순으로 정렬하는 예제
@Test
public void 조건1개_내림차순_정렬() {
// given
List<Book> books = new ArrayList<>();
books.add(makeBook(1, 7));
books.add(makeBook(2, 5));
books.add(makeBook(3, 9));
books.add(makeBook(4, 10));
books.add(makeBook(5, 4));
// when
List<Book> result = books.stream()
.sorted(Comparator.comparing(Book::getCreatedDate).reversed())
.collect(Collectors.toList());
log.debug("{}", result);
// then
assertThat(result.get(0).getId()).isEqualTo(4);
}
reversed를 사용하여 역순으로 변경했습니다.
조건2개를 오름차순으로 정렬하는 예제
@Test
public void 조건2개_시간_아이디_오름차순_정렬() {
// given
List<Book> books = new ArrayList<>();
books.add(makeBook(6, 7));
books.add(makeBook(7, 5));
books.add(makeBook(8, 9));
books.add(makeBook(9, 10));
books.add(makeBook(10, 4));
books.add(makeBook(1, 7));
books.add(makeBook(2, 5));
books.add(makeBook(3, 9));
books.add(makeBook(4, 10));
books.add(makeBook(5, 4));
// when
List<Book> result = books.stream()
.sorted(Comparator.comparing(Book::getCreatedDate).thenComparing(Book::getId))
.collect(Collectors.toList());
log.debug("{}", result);
// then
assertThat(result.get(0).getId()).isEqualTo(5);
}
thenComparing을 사용하면 조건을 연결할 수 있습니다.
직접구현하여 조건1개를 오름차순으로 정렬하는 예제
@Test
public void 조건1개_직접구현_오름차순_정렬() {
// given
List<Book> books = new ArrayList<>();
books.add(makeBook(1, 7));
books.add(makeBook(2, 5));
books.add(makeBook(3, 9));
books.add(makeBook(4, 10));
books.add(makeBook(5, 4));
// when
List<Book> result = books.stream().sorted((o1, o2) -> {
// o1.getCreatedDate() < o2.getCreatedDate()
if (o1.getCreatedDate().isBefore(o2.getCreatedDate())) {
return -1; // -1 이면 앞으로 정렬됨
} else {
return 1;
}
}).collect(Collectors.toList());
log.debug("{}", result);
// then
assertThat(result.get(0).getId()).isEqualTo(5);
}
sorted 인터페이스를 직접 구현했습니다. 비교 조건이 -1이 앞으로 1이 뒤로 정렬됩니다.
직접구현하여 조건2개를 시간은 내림차순 같은경우 아이디는 오름차순으로 정렬하는 예제
@Test
public void 조건2개_시간_내림차순_같으면_아이디_오름차순_정렬() {
// given
List<Book> books = new ArrayList<>();
books.add(makeBook(6, 7));
books.add(makeBook(7, 5));
books.add(makeBook(8, 9));
books.add(makeBook(9, 10));
books.add(makeBook(10, 4));
books.add(makeBook(1, 7));
books.add(makeBook(2, 5));
books.add(makeBook(3, 9));
books.add(makeBook(4, 10));
books.add(makeBook(5, 4));
// when
List<Book> result = books.stream().sorted((o1, o2) -> {
if (o1.getCreatedDate().isEqual(o2.getCreatedDate())) {
if (o1.getId().intValue() < o2.getId().intValue()) {
return -1;
} else {
return 1;
}
}
// o1.getCreatedDate() < o2.getCreatedDate()
if (o1.getCreatedDate().isBefore(o2.getCreatedDate())) {
return 1;
} else {
return -1;
}
}).collect(Collectors.toList());
log.debug("{}", result);
// then
assertThat(result.get(0).getId()).isEqualTo(4);
}
직접구현은 복잡한 조건을 구현해야할때 사용하면 좋습니다. 위의 예제는 일시가 동일한 경우 id조건으로 2번째 정렬 조건을 만들었습니다.
댓글
댓글 쓰기