자바 - Comparator 사용법

안녕하세요, 미래의 자바 마법사 여러분! ? 오늘 우리는 자바 Comparator의 세상을 함께 탐험해보겠습니다. 프로그래밍 초보자라도 걱정하지 마세요 - 저는 친절한 안내자가 되어 단계별로 안내해드릴게요. 이 튜토리얼이 끝나면 프로처럼 오브젝트를 정렬할 수 있을 거예요!

Java - Comparators

Comparator는 무엇인가요?

들어가기 전에, 책장을 정리하는 상상을 해보겠습니다. 책을 제목, 저자, 또는 출판일에 따라 정렬하고 싶을 수 있습니다. 자바에서 Comparator는 이러한 기준으로 책 모음을 정렬할 수 있는 개인 도서관리자와 같은 존재입니다.

기술적인 말로 하면, Comparator는 자바의 인터페이스로, 오브젝트에 대한 사용자 정의 정렬을 정의할 수 있게 해줍니다. 자연적인 정렬이 없는 오브젝트를 정렬하고 싶거나, 자연적인 정렬과 다른 방식으로 정렬하고 싶을 때 특히 유용합니다.

Comparator 인터페이스

Comparator 인터페이스를 좀 더 자세히 살펴보겠습니다:

public interface Comparator<T> {
int compare(T o1, T o2);
}

이것이 무서워하지 마세요! 보기보다 간단합니다. <T>는 이 인터페이스가 어떤 종류의 오브젝트로도 작동할 수 있음을 의미합니다. compare 메서드는 마법이 일어나는 곳입니다 - 도서관리자에게 두 책을 비교하게 요청하는 것과 같습니다.

compare 메서드의 작동 방식

compare 메서드는 두 오브젝트를 받아와서 정수를 반환합니다:

  • 첫 번째 오브젝트가 두 번째 오브젝트보다 "작다"고 간주될 때 음수를 반환합니다.
  • 동일하다고 간주될 때 영을 반환합니다.
  • 첫 번째 오브젝트가 두 번째 오브젝트보다 "크다"고 간주될 때 양수를 반환합니다.

이를 천정의 저울로 생각해보세요. 첫 번째 오브젝트가 가벼울 때 저울은 음수 쪽으로 기울고, 동일할 때는 균형을 유지하고, 첫 번째 오브젝트가 무거울 때는 양수 쪽으로 기울입니다.

첫 번째 Comparator 생성하기

이제 문자열의 길이에 따라 정렬하는 간단한 Comparator를 만들어보겠습니다. StringLengthComparator라고 부릅니다:

import java.util.Comparator;

public class StringLengthComparator implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}

이 작업에서는 다음이 일어납니다:

  1. java.util 패키지에서 Comparator 인터페이스를 임포트합니다.
  2. Comparator<String>를 구현하는 클래스를 생성하여 문자열 오브젝트를 비교합니다.
  3. compare 메서드를 오버라이드하여 두 문자열의 길이를 뺍니다.

Comparator 사용하기

이제 우리의 Comparator를 사용해보겠습니다! 문자열 목록을 생성하고 정렬해보겠습니다:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparatorExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Pear");
fruits.add("Banana");
fruits.add("Kiwi");

System.out.println("정렬 전: " + fruits);

Collections.sort(fruits, new StringLengthComparator());

System.out.println("정렬 후: " + fruits);
}
}

출력:

정렬 전: [Apple, Pear, Banana, Kiwi]
정렬 후: [Pear, Kiwi, Apple, Banana]

이를 좀 더 자세히 설명하자면:

  1. 과일 이름의 목록을 생성합니다.
  2. 원래 목록을 출력합니다.
  3. 우리의 커스텀 Comparator를 사용하여 목록을 정렬합니다.
  4. 정렬된 목록을 출력합니다.

과일 이름이 이제 길이에 따라 정렬되었음을 알 수 있습니다!

람다 표현식: 짧은 길이

자바 8에서 도입된 람다 표현식을 사용하면 Comparator를 더 간결하게 만들 수 있습니다. 다음은 람다 표현식을 사용한 동일한 예제입니다:

Collections.sort(fruits, (s1, s2) -> s1.length() - s2.length());

이 한 줄 코드는 StringLengthComparator 클래스와 정확히 같은 작업을 수행합니다! 자바에게 "두 문자열의 길이를 뺀 결과로 비교하라"고 말하는 것입니다.

커스텀 오브젝트 정렬하기

이제 커스텀 오브젝트를 정렬해보겠습니다. Person 클래스를 상상해보겠습니다:

public class Person {
private String name;
private int age;

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

// 게터와 세터...

@Override
public String toString() {
return name + " (" + age + ")";
}
}

Person 오브젝트를 나이로 정렬하는 Comparator를 만들어보겠습니다:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class PersonSortExample {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 30));
people.add(new Person("Charlie", 22));

System.out.println("정렬 전: " + people);

Collections.sort(people, Comparator.comparingInt(Person::getAge));

System.out.println("정렬 후: " + people);
}
}

출력:

정렬 전: [Alice (25), Bob (30), Charlie (22)]
정렬 후: [Charlie (22), Alice (25), Bob (30)]

여기서는 Comparator.comparingInt()를 사용하여 나이를 기준으로 정렬합니다. Person::getAge는 나이를 추출하는 메서드 참조입니다.

정렬 순서 반전하기

내림차순으로 정렬하고 싶다면 reversed() 메서드를 사용하면 됩니다:

Collections.sort(people, Comparator.comparingInt(Person::getAge).reversed());

이렇게 하면 Person 오브젝트를 연령대順으로 정렬합니다.

Comparator 연결하기

때로는 여러 기준으로 정렬하고 싶을 수 있습니다. 예를 들어, Person 오브젝트를 나이로 정렬하고, 나이가 같다면 이름으로 정렬하도록 합시다:

Comparator<Person> ageAndNameComparator = Comparator
.comparingInt(Person::getAge)
.thenComparing(Person::getName);

Collections.sort(people, ageAndNameComparator);

이렇게 하면 나이를 기준으로 정렬하고, 나이가 같다면 이름을 기준으로 정렬합니다.

결론

축하합니다! 자바 Comparator의 내막을 배웠습니다. 간단한 문자열에서 복잡한 오브젝트까지, 데이터를 원하는 대로 정렬할 수 있는 힘을 얻었습니다. 연습이 완벽을 이루는 길이니, 다양한 정렬 기준과 오브젝트를 실험해보세요.

자바 여정을 계속하면서 Comparator는 프로그래밍 도구箱에서 소중한 도구가 될 것입니다. 그들은 단순히 목록 정렬에만 사용되지 않습니다 - 많은 자바 컬렉션과 알고리즘에서 순서를 유지하고 효율적인 검색을 수행하는 데 사용됩니다.

계속 코딩하고, 학습하고, 가장 중요한 것은 즐겁게 하세요! 어쩌면有一天, 당신은 데이터를 정렬하는 방식을 혁신하는 정렬 알고리즘을 작성할지도 모릅니다. 그날까지, 행복하게 비교하세요! ??‍??‍?

Comparator 인터페이스의 메서드

Comparator 인터페이스의 주요 메서드 목록입니다:

메서드 설명
compare(T o1, T o2) 두 인자의 순서를 비교합니다.
equals(Object obj) 다른 오브젝트가 "동일한"지 여부를 나타냅니다.
reversed() 이 Comparator의 반대 순서를 반환합니다.
thenComparing(Comparator<? super T> other) 다른 Comparator와 혼합된 사전 순서 Comparator를 반환합니다.
thenComparingInt(ToIntFunction<? super T> keyExtractor) int 정렬 키를 추출하는 함수를 기준으로 사전 순서 Comparator를 반환합니다.
thenComparingLong(ToLongFunction<? super T> keyExtractor) long 정렬 키를 추출하는 함수를 기준으로 사전 순서 Comparator를 반환합니다.
thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) double 정렬 키를 추출하는 함수를 기준으로 사전 순서 Comparator를 반환합니다.

이 메서드들은 복잡한 정렬 로직을 만들기 위한 강력한 도구를 제공합니다. 어떤 데이터 타입이나 정렬 요구 사항에 맞게 Comparator를 작성할 수 있습니다.

Credits: Image by storyset