정렬할 때마다 아 Python 할 걸... 생각이 들게 하는 기능
근데 또 생각하려면 기억 안나서 계속 구글링해야하는 기능
정리해두려고합니다.
(회사에선 C#쓰면서 Java 못놓는 중,,,)
Arrays.sort
오름차순
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
String[] str = {"1", "5", "4", "3", "6", "2"};
for(String s : str) { // 정렬 전 출력
System.out.print(s + " ");
}
System.out.println();
Arrays.sort(str); // 정렬 후 출력
for(String s : str) {
System.out.print(s + " ");
}
}
}
1 5 4 3 6 2
1 2 3 4 5 6
내림차순
import java.util.Arrays;
import java.util.Collections;
public class Sort {
public static void main(String[] args) {
String[] str = {"1", "5", "4", "3", "6", "2"};
for(String s : str) { // 정렬 전 출력
System.out.print(s + " ");
}
System.out.println();
Arrays.sort(str, Collections.reverseOrder()); // 정렬 후 출력
for(String s : str) {
System.out.print(s + " ");
}
}
}
1 5 4 3 6 2
6 5 4 3 2 1
알고가야할 것 : 배열을 정렬할 땐, Arrays.sort() 사용하기
여기까진 쉽네
Collections.sort 와 Collections.reverse
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Sort {
public static void main(String[] args) {
String[] str = {"1", "5", "4", "3", "6", "2"};
List<String> list = Arrays.asList(str); // 배열 -> List
System.out.println(list); // 초기값
Collections.sort(list);
System.out.println(list); // 오름차순
Collections.reverse(list);
System.out.println(list); // 내림차순
}
}
[1, 5, 4, 3, 6, 2]
[1, 2, 3, 4, 5, 6]
[6, 5, 4, 3, 2, 1]
String[] 문자열은 되는 건 알겠는데 왜 int[] 숫자는 안돼...?
int[] 말고 Integer[] 로 하면 될거에요.
Integer[]는 되긴되네. 그런데 왜 int[] 는 안돼...?
Collections.sort() 메소드는 모든 "객체"를 사용할 수 있게끔 정의됐는데
int 는 primitive type 이라서 사용이 불가능합니다.
알고가야할 것 : list를 정렬할 땐, Collections.sort() 사용하기
Comparable Interface
숫자나 문자는 할만한데 새롭게 정의한 클래스가 있을 때 조금 까다로워져요...
새로운 기준을 잡아줘야 하기 때문입니다.
뭔 소리야...?
Student.name = '코린'
Student.score = '90'
이 경우, Student 라는 객체를 name? score? 어떤 변수로 비교할지 기준을 잡아줘야한다는 뜻입니다.
이 때 기준을 잡아주는 것이 Comparable 인터페이스이고
해당 인터페이스를 구현할 클래스에 compareTo 메소드를 오버라이딩하면 정렬이 가능한 클래스가 됩니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Student implements Comparable {
String name;
int score;
public Student (String name, int score) {
this.name = name;
this.score = score;
}
@Override
public int compareTo(Object o) {
Student other = (Student) o;
return other.score - this.score;
}
@Override
public String toString() {
return "name = " + name +
", score = " + score;
}
}
public class Sort {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("sim", 80));
list.add(new Student("kim", 90));
list.add(new Student("lee", 70));
list.add(new Student("park", 100));
System.out.println(list.toString());
Collections.sort(list);
System.out.println(list.toString());
}
}
[name = sim, score = 80, name = kim, score = 90, name = lee, score = 70, name = park, score = 100]
[name = park, score = 100, name = kim, score = 90, name = sim, score = 80, name = lee, score = 70]
JAVA는 오름차순이 디폴트입니다.
compareTo() 메소드 리턴값은 두 가지 경우의 수로 나뉠거에요.
1. return other.score - this.score
1) other.score > this.score 경우
other, this 로 되어있는 순서를 this, other로 바꿔야 오름차순이 되겠죠
2) other.score < this.score
other, this 로 되어있는 순서를 그대로 둬도 오름차순이 되겠죠
2. return this.score - other.score
1) this.score > other.score 경우
this, other 로 되어있는 순서를 other, this 로 바꿔야 오름차순이 되겠죠
2) this.score < other.score
other, this 로 되어있는 순서를 그대로 둬도 오름차순이 되겠죠
즉, 리턴값이 양수일 경우, 순서를 바꾸고 음수일 경우, 바꾸지 않는다는 결론입니다.
아... 무슨 말이야...
말이 굉장히 어렵습니다.... 예를 들어볼게요.
{100, 50} 으로 초기값이 세팅되어있고 이걸 정렬할거에요
this.score = '100'
other.score = '50'
return this.score - other.score = 50 이 되어 양수입니다.
양수는 순서를 바꾼다고 했죠?
{100, 50} 을 {50, 100} 순으로 순서를 바꾸니까 오름차순이 되었습니다.
내림차순으로 정렬하고 싶을 경우,
위에 return this.score - other.score일 경우, 오름차순이었으니
return other.score - this.score 로 변경하면 내림차순이 되겠죠.
머리 터진다...
그럼 다른 방법이 있는데 Comparator 인터페이스입니다.
Comparator
새롭게 정의한 클래스에 Comparable 인터페이스를 implements 했던 것과 다르게
Collections.sort(list, comparator) 의 형태로 정의 되어있어서 Comparator 은 메인 클래스에서 바로 사용할 수 있습니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Student {
String name;
int score;
public Student (String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "name = " + name +
", score = " + score;
}
}
public class Sort {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("sim", 80));
list.add(new Student("kim", 90));
list.add(new Student("lee", 70));
list.add(new Student("park", 100));
System.out.println(list.toString());
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.score - s2.score;
}
});
System.out.println(list.toString());
}
}
[name = sim, score = 80, name = kim, score = 90, name = lee, score = 70, name = park, score = 100]
[name = lee, score = 70, name = sim, score = 80, name = kim, score = 90, name = park, score = 100]
comparable은 기준(this)과 비교대상(other)이 있어 this.compareTo(other) 의 형태로 비교를 했다면,
comparator는 비교 대상 2개를 가지고 비교를 합니다.
JAVA는 오름차순이 디폴트이라고 했죠
compare() 메소드 리턴값도 두 가지 경우의 수로 나뉩니다.
1. return o1.score - o2.score
1) o1.score > o2.score 경우
o1, o2 로 되어있는 순서를 o2, o1로 바꿔야 오름차순이 되겠죠
2) o1.score < o2.score
o1, o2 로 되어있는 순서를 그대로 둬도 오름차순이 되겠죠
2. return o2.score - o1.score
1) o2.score > o1.score 경우
o2, o1 로 되어있는 순서를 o2, o1로 바꿔야 오름차순이 되겠죠
2) o2.score < o1.score
o2, o1 로 되어있는 순서를 그대로 둬도 오름차순이 되겠죠
compareTo 나 compare 이나 똑같네 ;
네 똑같네요.
차이점은
Comparable 은 클래스에 직접 interface 를 implements 하여 정렬가능한 클래스로 바꾸는 점
Comparator 은 Collections.sort(list, comparator) 의 형태로 정의 되어있어서 메인 클래스에서 바로 사용할 수 있다는 점
이 되겠습니다.
정렬 알고리즘 있을 때 꼭 필요한 내용이니까 최소 둘 중 하나는 외우시길 바랍니다.
끗 !
'IT > Java' 카테고리의 다른 글
[Java] String 객체가 메모리에서 어떻게 관리되나요? (0) | 2024.11.07 |
---|---|
Java에서 Stream API가 뭐에요? LinQ Stream 은 뭐에요? (0) | 2023.07.01 |
[JAVA 스터디][8주차] 인터페이스와 메서드 (0) | 2021.01.09 |
[JAVA 스터디][4주차-2] JUnit5 정의와 테스트 코드 예시 (0) | 2020.12.11 |
[JAVA 스터디][4주차-1] 제어문, 조건문, 반복문 (0) | 2020.12.11 |