기준
compare(a, b)가 음수면 a가 앞에 온다. 이 문장 하나를 기준으로 오름차순과 내림차순을 판단한다.
반환값의 의미
| 반환값 | 정렬 결과 |
|---|---|
| 음수 | a가 b보다 앞 |
| 양수 | b가 a보다 앞 |
| 0 | 같은 순서 |
오름차순은 작은 값이 앞이다.
Integer.compare(a, b)
내림차순은 큰 값이 앞이다.
Integer.compare(b, a)
숫자로 검산하기
헷갈리면 a = 3, b = 10을 넣는다.
내림차순이면 10이 앞에 와야 하므로 a = 3은 뒤로 가야 한다. 따라서 compare(a, b)는 양수가 나와야 한다.
Integer.compare(b, a)
Integer.compare(10, 3) // 양수
양수면 b가 앞에 온다. 그래서 내림차순은 b, a다.
동률 조건 작성 순서
정렬 기준이 여러 개일 때는 우선순위가 높은 조건부터 비교한다.
list.sort((a, b) -> {
if (a.score != b.score) {
return Integer.compare(b.score, a.score); // score 내림차순
}
return Integer.compare(a.id, b.id); // id 오름차순
});
베스트 앨범 문제에서는 다음과 같다.
| 기준 | 방향 |
|---|---|
| 재생 횟수 | 내림차순 |
| 고유 번호 | 오름차순 |
뺄셈 비교보다 Integer.compare
다음 방식은 짧지만 추천하지 않는다.
return b.score - a.score;
값 범위가 커지면 오버플로우가 날 수 있고, 정렬 방향도 헷갈리기 쉽다.
다음처럼 쓴다.
return Integer.compare(b.score, a.score);
Comparator.comparing도 가능하다
단일 기준이면 다음처럼 쓸 수 있다.
list.sort(Comparator.comparingInt(Song::play));
내림차순이면 reversed()를 붙인다.
list.sort(Comparator.comparingInt(Song::play).reversed());
여러 기준은 thenComparing으로 연결한다.
list.sort(
Comparator.comparingInt(Song::play).reversed()
.thenComparingInt(Song::id)
);
다만 코딩테스트 중 람다가 더 즉각적으로 읽히는 경우도 많다. 헷갈리면 직접 람다로 조건을 풀어 쓰는 편이 안전하다.
실수 체크
-
compare(a, b)음수면a가 앞이라는 기준을 떠올렸는가 - 내림차순에서
Integer.compare(b, a)를 썼는가 - 동률 조건을 문제 순서대로 넣었는가
-
a - b,b - a대신Integer.compare를 썼는가