Dino Rudy
[ETC] JAVA - 정렬, Comparator - 공룡 루디 본문
객체 배열 Arrays.sort()와 Comparator를 이용해 정렬

java.util.Arrays에서 제공하는 많은 메서드 중
정렬 메서드가 있습니다.
위 이미지에서 확인할 수 있듯이 Arrays에서 제공하는 sort()는 배열을 파라미터로 받습니다.
따라서 Collections에 포함되는 ArrayList나 LinkedList 타입은 Arrays.sort()의 파라미터가 되지 못합니다.
Arrays.sort()에 배열이 입력값으로 들어가게 되는데
일반적인 primitive 타입을 원소로 갖는 배열은 원소끼리의 비교가 가능하게 되어있습니다.
하지만 사용자가 정의한 클래스로부터 객체 배열을 생성한 경우
무엇을 기준으로 비교를 할지 기준을 정해줘야 합니다.
어떤 기준으로 정렬을 할지를 Comparator 인터페이스를 통해
익명 구현 객체를 만들고 compare() 함수를
오버라이딩하여 파라미터로 객체 배열과 함께 넘겨줘야 합니다.
import java.util.Arrays;
import java.util.Comparator;
class Student {
String name;
int id;
double score;
public Student() {
super();
}
public Student(String name, int id, double score) {
super();
this.name = name;
this.id = id;
this.score = score;
}
@Override
public String toString() {
return name + " " + id + " " + score;
}
}
public class Comparator1 {
public static <T> void main(String[] args) {
Student[] s = new Student[5];
s[0] = new Student("강호동", 20170301, 4.5);
s[1] = new Student("이수근", 20160301, 3.5);
s[2] = new Student("서장훈", 20180301, 2.5);
s[3] = new Student("김경훈", 20150301, 4.5);
s[4] = new Student("김희철", 20150302, 3.5);
Arrays.sort(s, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if (o1.score == o2.score) { // 학점이 같으면
// return o1.id - o2.id; // 학번으로 오름차순 정렬
return Integer.compare(o1.id, o2.id);
}
return Double.compare(o1.score, o2.score); // 학점으로 오름차순 정렬
}
});
//--------------출력
for (int i = 0; i < s.length; i++) {
System.out.println(s[i]);
}
}
}
compare함수는 두 개의 객체의 기준(사용자가 정함)을 비교하여
정수를 리턴합니다.
이때 리턴되는 정수가 양의 정수인지 음의 정수인지 0 인지에 따라
어떤 객체가 더 큰지를 알 수 있습니다.
만약 학점을 기준으로 오름차순 정렬을 한다고 했을 때
o1.score-o2.score을 하게 되면
o2.score가 o1.score보다 클 경우 음수가 리턴되게 되고
음수가 리턴되게 되면 순서가 유지됩니다.
두 비교 값이 같으면 0 리턴 (순서 유지)
(변수끼리 직접 빼도 되지만 Integer나 Double 클래스에서 제공하는 compare 함수를 써도 됩니다.
String 경우 compareTo() 이용)
o1.score가 o2.score보다 크면
양수를 받게 되고 교환을 합니다.
지금까지 객체 배열을 Arrays.sort()와 Comparator를 이용하여
정렬하는 방법이었습니다.
ArrayList, LinkedList 정렬하기

ArrayList와 LinkedList는 모두 List interface를 implements 한 클래스입니다.
List 인터페이스를 보면 sort() 함수는 default로 정의되어있어
ArrayList나 LinkedList에서는 따로 오버라이딩 되어있지 않습니다.
sort() 함수를 보면 Arrays.sort() 함수와 유사하게
Comparator 인터페이스를 구현한 익명 구현 객체를 파라미터로 달라고 합니다.
마찬가지로 사용자가 어떤 기준을 가지고 정렬을 할 것인지
정하여 파라미터로 넘겨 sort() 함수를 실행하면 정렬이 완성됩니다.
저도 아직 많이 익숙하지 않아 오름차순, 내림차순을 어떻게 써야 하는지 헷갈릴 때가 있습니다.
제가 주로 기억하는 방법은
보통 오름차순이 default이기 때문에 오름차순을 외웠고
두 객체가 주어졌을 때 앞에서 뒤를 빼는 것을 오름차순으로 외웠습니다.
(이때 뒤가 더 클 경우 음의 정수를 리턴하게 순서가 유지됩니다.(작은 게 앞으로 있어야 오름차순이 되기 때문))
import java.util.Comparator;
import java.util.LinkedList;
class Student {
String name;
int num;
double score;
public Student() {
super();
}
public Student(String name, int num, double score) {
super();
this.name = name;
this.num = num;
this.score = score;
}
@Override
public String toString() {
return name + " " + num + " " + score;
}
}
public class Comparator2 {
public static <T> void main(String[] args) {
LinkedList<Student> s = new LinkedList<>();
s.add(new Student("강호동", 20170301, 4.5));
s.add(new Student("이수근", 20160301, 3.5));
s.add(new Student("서장훈", 20180301, 2.5));
s.add(new Student("김경훈", 20150301, 4.5));
s.add(new Student("김희철", 20150302, 3.5));
// =====================================================
//ArrayList 정렬할 때 Comparator 오버라이딩
//LinkedList도 마찬가지
s.sort(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return (int) (o1.score-o2.score); //학점을 기준으로 오름차순
//앞에서 뒤 빼면 오름차순
}
});
// ---------------출력-----------------------------------------
for (int i = 0; i < s.size(); i++) {
System.out.println(s.get(i));
}
}
}

잘못된 부분이 있다면 댓글로 알려주세요:)
'Algorithm > ETC' 카테고리의 다른 글
| [ETC] JAVA - NextPermutation 함수 - 공룡 루디 (2) | 2022.01.08 |
|---|---|
| [ETC] JAVA - Union-Find - 공룡 루디 (0) | 2021.09.21 |
| [ETC] JAVA - 조합 2차원 배열 응용 - 공룡 루디 (0) | 2021.08.14 |
| [ETC] JAVA - 순열,중복 순열 구현 (비트마스크 활용 포함) - 공룡 루디 (0) | 2021.08.13 |
| [ETC] JAVA -조합, 중복조합 구현 - 공룡 루디 (0) | 2021.08.13 |