본문으로 건너뛰기

Sort

가장 기본형

List<Integer> list = new ArrayList<>();
list.add(10);
list.add(4);
list.add(6);
list.add(2);
list.add(8);
Collections.sort(list);
2
4
6
8
10

기본형을 역순으로

Collections.sort(list, Collections.reverseOrder());
10
8
6
4
2

Comparator를 사용한 정렬

public class SortExercise {
public static void main(String args[]) {

List<Integer> list = new ArrayList<>();
list.add(10);
list.add(4);
list.add(6);
list.add(2);
list.add(8);
Comparator comparator = new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return a.compareTo(b);
}
};
Collections.sort(list, comparator);

System.out.println(list);
}
}
[2, 4, 6, 8, 10]

위에것을 반대로

public class SortExercise {
public static void main(String args[]) {

List<Integer> list = new ArrayList<>();
list.add(10);
list.add(4);
list.add(6);
list.add(2);
list.add(8);
Comparator comparator = new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return a.compareTo(b);
}
};
Collections.sort(list, comparator.reversed());

System.out.println(list);
}
}
[10, 8, 6, 4, 2]

람다형으로

public class SortExercise {
public static void main(String args[]) {

List<Integer> list = new ArrayList<>();
list.add(10);
list.add(4);
list.add(6);
list.add(2);
list.add(8);
Collections.sort(list, (a, b) -> {
return a.compareTo(b);
});

System.out.println(list);
}
}
[2, 4, 6, 8, 10]

List<Map<Obj, Obj>>형일 때

public class SortExercise {
public static void main(String args[]) {

Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("name", "Amanda");
map1.put("age", 21);

Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("name", "Cavin");
map2.put("age", 15);

Map<String, Object> map3 = new HashMap<String, Object>();
map3.put("name", "Maria");
map3.put("age", 20);

Map<String, Object> map4 = new HashMap<String, Object>();
map4.put("name", "David");
map4.put("age", 18);

List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
list.add(map1);
list.add(map2);
list.add(map3);
list.add(map4);
Stream<Map<String, Object>> stream = list.stream();

List<Map<String, Object>> list2 = stream.sorted(SortExercise::comparator).collect(Collectors.toList());
for (Map<String, Object> m : list2) {
System.out.println(m.get("name") + " " + m.get("age"));
}
}
public static int comparator(Map<String, Object> map1, Map<String, Object> map2) {
if (map1 == null && map2 == null)
return 0;

if (map1 == null || map2 == null) {
throw new NullPointerException();
}

String name1 = (String) map1.get("name");
String name2 = (String) map2.get("name");
int c = name1.compareTo(name2);
if (c != 0)
return c;

int age1 = (int) map1.get("age");
int age2 = (int) map2.get("age");

return age2 - age1;
}
}
Amanda 21
Cavin 15
David 18
Maria 20

Comparable 과 Comparator

Comparable과 Comparator는 모두 인터페이스(interface) 즉, Comparable 혹은 Comparator을 사용하고자 한다면 인터페이스 내에 선언된 메소드를 '반드시 구현'해야한다.

Comparable은 "자기 자신과 매개변수 객체를 비교" compareTo(T o)를 오버라이드 하여 구현
Comparator는 "두 매개변수 객체를 비교" compare(T o1, T o2) 를 오버라이드 하여 구현

Comparable

public class ClassName implements Comparable<Type> { 

/*
...
code
...
*/

// 필수 구현 부분
@Override
public int compareTo(Type o) {
/*
비교 구현
*/
}
}

이렇게 보통은 배우는데

class Student implements Comparable<Student> {

int age; // 나이
int classNumber; // 학급

Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}

@Override
public int compareTo(Student o) {

// 자기자신의 age가 o의 age보다 크다면 양수
if(this.age > o.age) {
return 1;
}
// 자기 자신의 age와 o의 age가 같다면 0
else if(this.age == o.age) {
return 0;
}
// 자기 자신의 age가 o의 age보다 작다면 음수
else {
return -1;
}
}
}

이런식으로 두 값의 차를 반환해버리면 번거로운 조건식 없이 한방에 3개의 조건을 만족할 수 있다.

class Student implements Comparable<Student> {

int age; // 나이
int classNumber; // 학급

Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}

@Override
public int compareTo(Student o) {

/*
* 만약 자신의 age가 o의 age보다 크다면 양수가 반환 될 것이고,
* 같다면 0을, 작다면 음수를 반환할 것이다.
*/
return this.age - o.age;
}
}

Comparator

import java.util.Comparator;    // import 필요
public class ClassName implements Comparator<Type> {

/*
...
code
...
*/

// 필수 구현 부분
@Override
public int compare(Type o1, Type o2) {
/*
비교 구현
*/
}
}

기본형은 이렇게 사용하는데

import java.util.Comparator;    // import 필요
class Student implements Comparator<Student> {
int age;            // 나이
int classNumber; // 학급

Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}

@Override
public int compare(Student o1, Student o2) {

// o1의 학급이 o2의 학급보다 크다면 양수
if(o1.classNumber > o2.classNumber) {
return 1;
}
// o1의 학급이 o2의 학급과 같다면 0
else if(o1.classNumber == o2.classNumber) {
return 0;
}
// o1의 학급이 o2의 학급보다 작다면 음수
else {
return -1;
}
}

}


> 이렇게도 쓴다

```java
import java.util.Comparator; // import 필요
class Student implements Comparator<Student> {

int age; // 나이
int classNumber; // 학급

Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}

@Override
public int compare(Student o1, Student o2) {

/*
* 만약 o1의 classNumber가 o2의 classNumber보다 크다면 양수가 반환 될 것이고,
* 같다면 0을, 작다면 음수를 반환할 것이다.
*/
return o1.classNumber - o2.classNumber;
}
}