[Java] Comparator, Lamda 사용하여 2차원 배열 정렬하기
오름차순, 내림차순 등 정렬을 할 때 음수가 나와야 오름차순인지, 양수가 나와야 오름차순인지 항상 헷갈려서 기억하기 위해 잘 정리된 포스팅을 참고하여 남겼다.
2차원 배열을 바로 Arrray.sort()를 통해 정렬하려고 하면, 비교 기준이 구현되어 있지 않기 때문에 캐스팅에 실패했다는 java.lang.ClassCastException: I cannot be cast to java.lang.Comparable 오류가 발생한다.
그 해결책으로 Comparable,Comparator 인터페이스를 구현하여 정렬기준을 추가해 2차원배열 뿐만 아니라 객체비교할 때도 사용할 수 있다.
int[][] arr = new int[][]{{5,10},{3,30},{1,50},{4,20},{2,40},{5,60}};
Arrays.sort(arr); //java.lang.ClassCastException: I cannot be cast to java.lang.Comparable
1. Comparator 익명 클래스 구현
int[][] arr = new int[][]{{5,40},{3,50},{1,30},{4,20},{2,10}};
// 1. Comparator 익명 클래스 구현
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0]-o2[0]; // 첫번째 숫자 기준 오름차순 {1,30}{2,10}{3,50}{4,20}{5,40}
//return o2[0]-o1[0]; // 첫번째 숫자 기준 내림차순 {5,40}{4,20}{3,50}{2,10}{1,30}
//return o1[1]-o2[1]; // 두번째 숫자 기준 오름차순 {2,10}{4,20}{1,30}{5,40}{3,50}
//return o2[1]-o1[1]; // 두번째 숫자 기준 내림차순 {3,50}{5,40}{1,30}{4,20}{2,10}
}
});
// 다중 조건
int[][] arr2 = new int[][]{{5,40},{3,50},{1,30},{4,20},{2,10},{6,40},{6,50},{6,10},{6,20},{6,30}};
Arrays.sort(arr2, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0]!=o2[0] ? o1[0]-o2[0] : o1[1]-o2[1];
// 첫번째 기준 오름차순 > 두번째 기준 오름차순 : {1,30}{2,10}{3,50}{4,20}{5,40}{6,10}{6,20}{6,30}{6,40}{6,50}
//return o1[0]!=o2[0] ? o1[0]-o2[0] : o2[1]-o1[1];
// 첫번째 기준 오름차순 > 두번째 기준 내림차순 : {1,30}{2,10}{3,50}{4,20}{5,40}{6,50}{6,40}{6,30}{6,20}{6,10}
}
});
전통적으로 사용하던 Comparator 익명클래스 구현하는 방법으로 compare() 메서드를 오버라이드하여 원하는 정렬 기준을 명시해준다. 오름차순, 내림차순 외에 원하는 조건으로도 구현이 가능하며 2차원 배열 뿐만 아니라 비교 가능한 모든 클래스에서 사용 가능하다.
2. Lambda 사용 - Java 8이상
int[][] arr = new int[][]{{5,40},{3,50},{1,30},{4,20},{2,10}};
// 2. Lambda 사용 - Java 8이상
Arrays.sort(arr, (o1, o2) -> {
return o1[0]-o2[0]; // 첫번째 숫자 기준 오름차순 {1,30}{2,10}{3,50}{4,20}{5,40}
});
Java8 버전 이상에서는 람다식(Lambda)을 이용해서 조금 더 간결하게 구현이 가능하다.
3. Comparator.comparing() 사용
int[][] arr = new int[][]{{5,40},{3,50},{1,30},{4,20},{2,10}};
// 3. Comparator.comparing()
Arrays.sort(arr, Comparator.comparingInt((int[] o) -> o[0])); // 첫번째 숫자 기준 오름차순 : {1,30}{2,10}{3,50}{4,20}{5,40}
Arrays.sort(arr, Comparator.comparingInt((int[] o) -> o[0]).reversed()); // 첫번째 숫자 기준 내림차순 : {5,40}{4,20}{3,50}{2,10}{1,30}
Arrays.sort(arr, Comparator.comparingInt((int[] o) -> o[1])); // 두번째 숫자 기준 오름차순 : {2,10}{4,20}{1,30}{5,40}{3,50}
Arrays.sort(arr, Comparator.comparingInt((int[] o) -> o[1]).reversed()); // 두번째 숫자 기준 내림차순 : {3,50}{5,40}{1,30}{4,20}{2,10}
Comparator의 comparing 메서드를 이용하는 방법이다. 예제는 int타입이기 때문에 comparingInt 메서드가 사용되었다.
다중 조건으로 정렬하려면 메서드 체이닝(Method Chaining) 통해 정렬해 나가면 된다.
이 방법은 아직 제대로 익숙해지지 않았다. 자주 사용해봐야지...
'JAVA > Java' 카테고리의 다른 글
[Java] 문자열, 객체, 배열 Null Check (0) | 2022.12.12 |
---|---|
[Java] 객체 매핑 라이브러리 ModelMapper 살펴보자 (1) | 2022.12.12 |
[Java] Java Stream 활용하여 두 개의 List 객체 비교하기 (0) | 2022.12.12 |
[Java] 중복 키 허용 MultiValueMap 와 HashMap 차이 (0) | 2022.12.12 |
[Java] Arrays.sort 와 Collections.sort 정리 (0) | 2022.12.12 |
[Java] StringTokenizer Class 사용 및 Split 비교 (0) | 2022.12.12 |
[Java] 스트림 (Stream) 타입별 변환 (0) | 2022.12.12 |
[Java] POI 엑셀 다운로드 시 Invalid char (/) found at index (6) in sheet name 에러 (0) | 2022.12.12 |