JAVA를 다루다 보면, 배열이나 객체를 정렬할 일이 있습니다. 이때에는 직접 정렬시키는 방법도 있겠으나, 보통은 자바 클래스 라이브러리에서 제공하는 메서드를 사용합니다.
이때 보통 Arrays.sort() 혹은 Collections.sort() 메소드를 통해 배열 혹은 리스트에 대한 정렬을 합니다.
이번 포스팅에서는 Arrays.sort()과 Collections.sort() 메서드를 알아보겠습니다.
Array.sort()❓
Arrays.sort(배열);
- 오름차순으로 정렬하고 싶은 배열을 전달인자로 주면 전달인자로 받은 배열이 정렬됩니다.
- 문자열의 경우 아스키코드 순 (알파벳 순)으로 오름차순 정렬되며, 한글도 가나다 순으로 정렬됩니다.
위와 같이 괄호 안에 정렬할 대상이 되는 배열을 넣어주기만 하면 돼서 매우 간편합니다. 이는 int형, String형 모두 오름차순 정렬에 사용할 수 있습니다.
int[] intArr = new int[] {1,3,5,2,4};
double[] doubletArr = new double[] {1.1, 3.3, 5.5, 2.2, 4.4};
String[] stringArr = new String[] {"A","C","F","E","D"};
// 전체 정렬
System.out.println(Arrays.sort(intArr)); // 결과 : 1 2 3 4 5
Arrays.sort(doubletArr); // 결과 : 1.1 2.2 3.3 4.4 5.5
Arrays.sort(stringArr); // 결과 : A B C D E
// 부분 정렬
Arrays.sort(intArr, 1, 4); // 결과 : 1 2 3 5 4
그렇다면 내림차순은 다음과 같이 sort()로 정렬된 배열을 역순으로 보여주면 됩니다.
import java.io.IOException;
import java.util.Arrays;
public class Main {
public static void main(String args[]) throws IOException {
int[] num = new int[] {1,3,5,2,4};
for (int i = num.length - 1; i >= 0; i--) { // 숫자 내림차순 정렬
System.out.print(num[i] + " ");
}
// 5 4 3 2 1
}
}
collections.reverseOrder()
Arrays.sort(배열, Collections.reverseOrder());
오름차순 정렬이 아닌, 내림차순이나 임의의 정렬기준을 적용하려면 Comparator 를 구현한 클래스를 전달인자로 주어, 원하는 방식대로 정렬할 수 있습니다.
import java.io.IOException;
import java.util.Arrays;
public class Main {
public static void main(String args[]) throws IOException {
int[] num = new int[] {1,3,5,2,4};
Arrays.sort(num,Collections.reverseOrder()); // 내림차순 정렬
System.out.println(num); // 결과 : 5 4 3 2 1
}
}
이 때 주의해야 할 점이 있습니다. 바로 Collections.reverseOrder()으로 배열을 내림차순으로 정렬하고자 할 때 해당 배열은 기본타입(Primitive type)이 아닌 래퍼 클래스(Wrapper class)이어야 합니다.
왜냐하면 Comparator는 제네릭 타입을 사용하는 데 제네릭 타입은 기본 자료형(primitive type)을 직접 지원하지 않기 때문에, 기본 자료형을 래퍼 클래스 객체로 변환해야 합니다.
기본 자료형 ➡️ 래퍼클래스
import java.util.Arrays;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
// 기본 자료형 배열 (int)
int[] primitiveNumbers = {5, 3, 8, 1, 2};
// 기본 자료형 배열을 래퍼 클래스 배열로 변환 (Integer)
Integer[] wrapperNumbers = Arrays.stream(primitiveNumbers).boxed().toArray(Integer[]::new);
// Collections.reverseOrder()를 사용하여 내림차순 정렬
Arrays.sort(wrapperNumbers, Collections.reverseOrder());
System.out.println(Arrays.toString(wrapperNumbers)); // [8, 5, 3, 2, 1]
}
}
Comparator 란❓
Comparator는 자바에서 객체의 순서를 정의하는 방법을 제공하는 인터페이스입니다.
사용자는 이 인터페이스를 직접 구현한 클래스를 만들 수 있습니다. 이미 구현되어 있는 구현체를 사용할 수 있습니다.
Collections.sort()❓
Collections.sort()는 java.util.Collections 클래스에 정의된 정적 메서드로, 리스트(List)를 정렬하는 데 사용됩니다.
Collections.sort()에는 두 가지 오버로딩된 버전이 있습니다.
- 기본 정렬 순서를 사용하는 메서드
- Comparator를 사용하는 메서드
기본 정렬 순서 : Collections.sort(List <T> list)
리스트의 요소가 Comparable 인터페이스를 구현해야 하며, 이를 통해 자연 순서(natural order)로 정렬됩니다.
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
// 기본 정렬 순서로 정렬 (오름차순)
Collections.sort(numbers);
System.out.println(numbers); // [1, 2, 3, 5, 8]
}
}
자연순서 : 객체의 기본적인 정렬 순서를 나타냅니다. Java에서 자연 순서는 대부분의 경우 객체의 Comparable 인터페이스에 의해 정의됩니다.
• 객체 A가 객체 B보다 작으면 음수를 반환합니다.
• 객체 A가 객체 B와 같으면 0을 반환합니다.
• 객체 A가 객체 B보다 크면 양수를 반환합니다.
Comparator 사용 : Collections.sort(List<T> list, Comparator <? super T> c)
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> words = new ArrayList<>(Arrays.asList("apple", "banana", "cherry", "date"));
// 람다 표현식을 사용하여 문자열 길이로 정렬
Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
System.out.println(words); // [date, apple, banana, cherry]
}
}
Collections.sort() VS Arrays.sort()
표면적으로 보면 정렬 대상이 배열이면 Arrays을 사용하고, 정렬 대상이 그 외 리스트와 같은 객체이면 Collections을 사용하면 될 것 같지만 가장 중요한 차이점은 정렬방식의 차이입니다.
Arrays.sort()와 Collections.sort()에 사용되는 정렬 방식이 다른 이유는 배열과 리스트 자료구조의 차이점 때문입니다.
정렬 방식시간 복잡도
Arrays.sort() | Dual Pivot Quicksort | 평균 : O(nlog(n)) / 최악 : O(n^2) |
Collections.sort() | TimeSort (삽입정렬 +합병정렬) | 평균, 최악 : O(nlog(n)) |
Dual Pivot Quicksort는 평균 시간복잡도가 O(nlogn)으로 매우 빠른 알고리즘입니다. 그러나 최악에서는 O(n^2)라는 것을 인지해야 합니다.
QuickSort는 평균적으로 매우 빠른 속도를 보이는 효율적인 정렬 알고리즘 중 하나입니다.
하지만 QuickSort는 안정성(stability)을 보장하지 않는데, 이는 동일한 값에 대해 정렬을 수행했을 때 원래의 상대적인 순서가 유지되지 않을 수 있다는 것을 의미합니다.
이는 특히 객체 배열에서 정렬을 수행할 때 문제가 될 수 있습니다.
따라서 Quick sort는 배열에서 좋은 성능을 보이지만 stable 하지않아서 stable이 필요한 Object에는 Collections.sort()가 많이 쓰입니다.
'Language > Java' 카테고리의 다른 글
[JAVA] 더블 콜론 연산자 :: 알아보기 (메서드 참조 사용 방법과 예제) (0) | 2024.06.02 |
---|---|
[Java] toCharArray() 메소드 알아보기 (문자열 ➡️ char배열) (1) | 2024.06.02 |
[JAVA] contains() 메소드 알아보기 (문자열 포함 여부 확인) (0) | 2024.05.23 |
[JAVA] Stream API에 대해 알아보기 _ Stream 최종 연산 Collect()(집계) (5/5) (1) | 2024.05.22 |
[JAVA] Optional 클래스에 대해 알아보기 (0) | 2024.05.19 |