정렬(Sort)

Comparator + 람다식 → 커스텀 정렬


1. 기본 구조

Arrays.sort(배열, (a, b) -> {
    return 비교값;
});

1.1 Comparator 람다식 반환값 기준

반환값

의미

정렬 결과

음수 (< 0)

a가 b보다 작다

a가 앞에 옴

0

a와 b가 같다

순서 유지

양수 (> 0)

a가 b보다 크다

b가 앞에 옴


2. 자주 사용하는 커스텀 정렬

2.1 오름차순 정렬 (작은 수 → 큰 수)

Arrays.sort(arr, (a, b) -> a - b);

2.2 내림차순 정렬 (큰 수 → 작은 수)

Arrays.sort(arr, (a, b) -> b - a);

2.3 절댓값 기준 오름차순 정렬

Arrays.sort(arr, (a, b) -> Math.abs(a) - Math.abs(b));

2.4 절댓값 기준 + 값이 같으면 큰 수 우선

Arrays.sort(arr, (a, b) -> {
    int diff = Math.abs(a) - Math.abs(b);
    if (diff == 0) return b - a; // 절댓값 같으면 큰 수 우선
    return diff;
});

3. 정리

목적

정렬식

기본 오름차순

(a, b) -> a - b

기본 내림차순

(a, b) -> b - a

절댓값 기준

(a, b) -> Math.abs(a) - Math.abs(b)

절댓값 + 값이 같으면 큰 수 우선

(a, b) -> { ... if문으로 처리 }


4. List 정렬

4.1 기본 오름차순 정렬

List<Integer> list = Arrays.asList(3, 1, 5, 2);
Collections.sort(list);  // 기본 오름차순

4.2 내림차순 정렬 (람다식 사용)

list.sort((a, b) -> b - a);  // 또는 Collections.sort(list, (a, b) -> b - a);

4.3 절댓값 기준 정렬

list.sort((a, b) -> Math.abs(a) - Math.abs(b));

5. 객체 정렬

5.1 방법 1: Comparable 인터페이스 (자기 자신 기준 정렬)

예시 클래스

class Person implements Comparable<Person> {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person other) {
        return this.age - other.age;  // 나이 오름차순 정렬
    }
}

사용 방법

List<Person> list = new ArrayList<>();
list.add(new Person("Alice", 25));
list.add(new Person("Bob", 20));
Collections.sort(list);  // compareTo() 기준으로 정렬됨

5.2 방법 2: Comparator 인터페이스 (외부 기준 정렬)

예시 1: 이름 기준 정렬 (오름차순)

list.sort(Comparator.comparing(p -> p.name));

예시 2: 나이 내림차순 정렬

list.sort((p1, p2) -> p2.age - p1.age);

6. 정리 요약

구분

인터페이스

사용 위치

정렬 기준 변경

Comparable

compareTo()

클래스 내부 정의

고정 (자기 기준)

Comparator

compare()

외부에서 전달

유동적 (다양한 기준 가능)



Map 정렬


1. Map을 키 기준으로 정렬

Map<String, Integer> map = new HashMap<>();
map.put("apple", 3);
map.put("banana", 1);
map.put("cherry", 2);

// 키 기준 오름차순 정렬
Map<String, Integer> sortedByKey = new TreeMap<>(map);

2. Map을 값 기준으로 정렬

List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());

// 값 기준 오름차순 정렬
entries.sort(Map.Entry.comparingByValue());

// 값 기준 내림차순 정렬
entries.sort((a, b) -> b.getValue() - a.getValue());

3. 정렬된 Map 만들기

Map<String, Integer> sortedMap = new LinkedHashMap<>();
for (Map.Entry<String, Integer> entry : entries) {
    sortedMap.put(entry.getKey(), entry.getValue());
}


PriorityQueue 정렬 기준


1. 오름차순 우선순위 큐 (작은 값이 먼저)

PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(5);
pq.add(2);
pq.add(8);

2. 내림차순 우선순위 큐 (큰 값이 먼저)

PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);

3. 사용자 정의 객체 정렬

class Person {
    String name;
    int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

PriorityQueue<Person> pq = new PriorityQueue<>((p1, p2) -> p1.age - p2.age); // 나이 오름차순


Java Stream 정렬


1. 기본 정렬 (숫자 오름차순)

List<Integer> list = Arrays.asList(5, 3, 1, 4);
List<Integer> sorted = list.stream()
    .sorted()
    .collect(Collectors.toList());

2. 내림차순 정렬

List<Integer> sortedDesc = list.stream()
    .sorted(Comparator.reverseOrder())
    .collect(Collectors.toList());

3. 객체 리스트 정렬

List<Person> people = Arrays.asList(
    new Person("Alice", 25),
    new Person("Bob", 20)
);

// 나이 기준 오름차순
List<Person> sortedPeople = people.stream()
    .sorted(Comparator.comparing(p -> p.age))
    .collect(Collectors.toList());

4. 여러 기준으로 정렬

// 나이 기준, 같으면 이름 기준
.sorted(Comparator.comparing(Person::getAge)
                 .thenComparing(Person::getName))