[Java] Comparator로 문자열 정렬
June 10, 2024
Java에서 Comparator로 문자열 리스트를 정렬할 수 있습니다. Comparator는 어떻게 정렬할지에 대한 내용이 구현되어있는 객체입니다. 이 객체를 리스트의 sort()
함수에 전달하면 Comparator의 규칙에 맞게 정렬됩니다.
Comparator
Comparator<T>
는 함수형 인터페이스이고, compare()
메소드를 갖고 있습니다.
compare()
는 인자 o1과 o2 객체를 비교하고 결과를 리턴
비교 결과는 음수, 0, 양수 중에 하나이며, 각각 의미는 다음과 같습니다. 비교 결과로 리스트를 정렬을 할 수 있습니다.
- 음수 : o1이 o2보다 작음
- 0 : o1과 o2와 같음
- 양수 : o1이 o2보다 큼
@FunctionalInterface
public interface Comparator<T> {
/**
* Compares its two arguments for order. Returns a negative integer,
* zero, or a positive integer as the first argument is less than, equal
* to, or greater than the second.
*
* @param o1 the first object to be compared.
* @param o2 the second object to be compared.
* @return a negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than the
* second.
*/
int compare(T o1, T o2);
}
Comparator는 다음과 같이 구현하여 사용할 수 있습니다.
- 클래스 파일을 만들고 구현을 추가할 수 있지만, 1회성으로 사용된다면 익명 클래스나, 람다식 또는 메소드 레퍼런스로 구현하여 인자로 전달함
List.sort(Comparator)
대신에Collections.sort(List, Comparator)
를 사용할 수도 있음
List<String> stringList = new ArrayList<>();
stringList.add("Apple");
stringList.add("Banana");
stringList.add("Cherry");
// 1) 익명 클래스로 구현
stringList.sort(new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
});
// 2) 람다식
stringList.sort((s1, s2) -> Integer.compare(s1.length(), s2.length()));
// 3) 메소드 레퍼런스(Method References)를 이용한 방법
stringList.sort(Comparator.comparingInt(String::length));
// 4) Collections.sort() 이용
Collections.sort(stringList, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
Comparator로 문자열 리스트 정렬
아래 예제는 Comparator를 구현하여 문자열 리스트를 정렬합니다.
주석을 보면, 길이로 정렬하는 부분이 있는데, Integer.compare()
로 길이를 비교하여 정렬합니다. 정렬 순서를 반대로 뒤집으면 오름차순 정렬이 내림차순 정렬로 됩니다.
- 문자열을 길이로 오름차순 정렬
- 문자열을 길이로 내림차순 정렬
또한, 알파벳 순서로 정렬하는 것도 있는데, String.compareTo()
를 이용하여 문자열의 알파벳 순서로 비교합니다. 이것도 비교 순서를 반대로하여 역순으로 정렬할 수도 있습니다.
- 문자열을 알파벳 순으로 정렬
- 문자열을 알파벳 역순으로 정렬
만약 문자열을 다른 방식으로 정렬하고 싶다면, 직접 Comparator의 compare()
함수를 구현하시면 됩니다. 비교 결과에 따라서 음수, 0, 양수 값만 잘 리턴하면 됩니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Example {
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
stringList.add("Apple");
stringList.add("Banana");
stringList.add("Cherry");
stringList.add("Date");
stringList.add("Grape");
// 문자열을 길이로 오름차순 정렬
Collections.sort(stringList, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
});
System.out.println("문자열을 길이로 오름차순 정렬:");
for (String str : stringList) {
System.out.println(str);
}
// 문자열을 길이로 내림차순 정렬
Collections.sort(stringList, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s2.length(), s1.length());
}
});
System.out.println("\n문자열을 길이로 내림차순 정렬:");
for (String str : stringList) {
System.out.println(str);
}
// 문자열을 알파벳 순으로 정렬
Collections.sort(stringList, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
System.out.println("\n문자열을 알파벳 순서로 정렬:");
for (String str : stringList) {
System.out.println(str);
}
// 문자열을 알파벳 역순으로 정렬
Collections.sort(stringList, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s2.compareTo(s1);
}
});
System.out.println("\n문자열을 알파벳 역순으로 정렬:");
for (String str : stringList) {
System.out.println(str);
}
}
}
Output:
문자열을 길이로 오름차순 정렬:
Date
Apple
Grape
Banana
Cherry
문자열을 길이로 내림차순 정렬:
Banana
Cherry
Apple
Grape
Date
문자열을 알파벳 순서로 정렬:
Apple
Banana
Cherry
Date
Grape
문자열을 알파벳 역순으로 정렬:
Grape
Date
Cherry
Banana
Apple
람다식, 메소드 레퍼런스를 이용하여 간단히 구현
위의 예제에서 Comparator 구현 방식을 람다식, 메소드 레퍼런스를 이용하면 더 짧은 코드로 동일한 내용을 구현할 수 있습니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Example {
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
stringList.add("Apple");
stringList.add("Banana");
stringList.add("Cherry");
stringList.add("Date");
stringList.add("Grape");
// 문자열을 길이로 오름차순 정렬
Collections.sort(stringList, Comparator.comparingInt(String::length));
System.out.println("문자열을 길이로 오름차순 정렬:");
for (String str : stringList) {
System.out.println(str);
}
// 문자열을 길이로 내림차순 정렬
Collections.sort(stringList, (s1, s2) -> Integer.compare(s2.length(), s1.length()));
System.out.println("\n문자열을 길이로 내림차순 정렬:");
for (String str : stringList) {
System.out.println(str);
}
// 문자열을 알파벳 순으로 정렬
Collections.sort(stringList, String::compareTo);
System.out.println("\n문자열을 알파벳 순서로 정렬:");
for (String str : stringList) {
System.out.println(str);
}
// 문자열을 알파벳 역순으로 정렬
Collections.sort(stringList, Comparator.reverseOrder());
System.out.println("\n문자열을 알파벳 역순으로 정렬:");
for (String str : stringList) {
System.out.println(str);
}
}
}