기준

compare(a, b)가 음수면 a가 앞에 온다. 이 문장 하나를 기준으로 오름차순과 내림차순을 판단한다.

반환값의 의미

반환값정렬 결과
음수ab보다 앞
양수ba보다 앞
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를 썼는가