package src;
import java.util.*;
// Ex) ArrayList, LinkedList, Vector 등 * 내부적으로 Arrays.sort()를 사용
class People implements Comparable<People> {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public People(String name, int age){
this.name = name;
this.age= age;
}
@Override
public int compareTo(People people) {
if (this.age < people.age) {
return -1;
} else if (this.age == people.age) {
return 0;
} else {
return 1;
}
}
}
package src;
class Point implements Comparable<Point> {
// 현재 객체 < 파라미터로 넘어온 객체: 음수 리턴
// 현재 객체 == 파라미터로 넘어온 객체: 0 리턴
// 현재 객체 > 파라미터로 넘어온 객체: 양수 리턴
// 음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우에는 두 객체의 자리가 바뀐다.
int x, y;
Point(int x,int y){
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public int compareTo(Point p) {
if(this.x > p.x) {
return 1; // x에 대해서는 오름차순
}
else if(this.x == p.x) { // x좌표가 같으면
if(this.y < p.y) { // y에 대해서는 내림차순
return 1;
}
}
return -1;
}
}
package src;
import java.util.*;
public class Sort {
public static void main(String[] args) {
// 기본타입 배열 오름차순
int arr[] = {4,23,33,15,17,19};
Arrays.sort(arr);
for (int i : arr) {
System.out.print("["+i+"]");
}
System.out.println();
// String 배열 오름차순 기본 타입과 동일
// ----------------------------------------------------------------
String arr2[] = {"apple","orange","banana","pear","peach","melon"};
Arrays.sort(arr2);
for (String i : arr2) {
System.out.print("["+i+"]");
}
System.out.println();
// 기본타입 배열 내림차순 정렬
// ----------------------------------------------------------------
Integer arr3[] = {4,23,33,15,17,19};
Arrays.sort(arr3,Collections.reverseOrder());
for (int i : arr3) {
System.out.print("["+i+"]");
}
String arr4[] = {"apple","orange","banana","pear","peach","melon"};
Arrays.sort(arr4,Collections.reverseOrder());
System.out.println();
// String 배열 내림차순 정렬
// ----------------------------------------------------------------
for (String i : arr4) {
System.out.print("["+i+"]");
}
int arr5[] = {4,23,33,15,17,19};
// int[] arr5 = {4,23,33,15,17,19};
// int[] arr5 = new int[] {4,23,33,15,17,19};
// int arr5[] = new int[] {4,23,33,15,17,19};
// 다 동일
Arrays.sort(arr5, 0, 4); // 0,1,2,3 요소만 정렬
System.out.println();
// 배열 일부분만 정렬
// ----------------------------------------------------------------
for (int i : arr5) {
System.out.print("["+i+"]");
}
System.out.println();
// 객체 배열 정렬할시에는 comparable 이나 comparator을 사용해야 한다.
// ----------------------------------------------------------------
People[] arr6 = { new People("상현", 20)
, new People("철수", 14)
, new People("경완", 31)
, new People("대호", 40)
, new People("지운", 24)
};
Arrays.sort(arr6); //오름차순 정렬
for (People i : arr6) { //오름차순 출력
System.out.print("["+ i.getName() + i.getAge() +"]");
}
Arrays.sort(arr6,Collections.reverseOrder()); // [철수(14)][상현(20)][지운(24)][경완(31)][대호(40)]
System.out.println();
for (People i : arr6) { //내림차순 출력
System.out.print("["+i.getName() + i.getAge()+"]"); //[대호(40)][경완(31)][지운(24)][상현(20)][철수(14)]
}
// ------------------------------------------------- Comparable
System.out.println();
List<Point> pointList = new ArrayList<>();
pointList.add(new Point(5 , 4));
pointList.add(new Point(3 , 9));
pointList.add(new Point(2 , 1));
Collections.sort(pointList);
for (Point i : pointList) {
System.out.print(" X : "+ i.getX() + " Y : "+ i.getY());
System.out.println();
}
System.out.println();
// -------------------------------------------------- Comparator
// 만약 정렬 대상 클래스의 코드를 직접 수정할 수 없는 경우에는 어떻게 객체의 정렬 기준을 정의할 수 있을까요?
// 또는 정렬 하고자 하는 객체에 이미 존재하고 있는 정렬 기준과 다른 정렬 기준으로 정렬을 하고 싶을 때는 어떻게 해야할까요?
// 첫 번째 파라미터로 넘어온 객체 < 두 번째 파라미터로 넘어온 객체: 음수 리턴
// 첫 번째 파라미터로 넘어온 객체 == 두 번째 파라미터로 넘어온 객체: 0 리턴
// 첫 번째 파라미터로 넘어온 객체 > 두 번째 파라미터로 넘어온 객체: 양수 리턴
Comparator<Point> myComparator = new Comparator<Point>() {
@Override
public int compare(Point p1, Point p2) {
if (p1.x > p2.x) {
return 1; // x에 대해서는 오름차순
}
else if (p1.x == p2.x) {
if (p1.y < p2.y) { // y에 대해서는 내림차순
return 1;
}
}
return -1;
}
};
List<Point> pointList2 = new ArrayList<>();
pointList2.add(new Point(1, 5));
pointList2.add(new Point(5, 19));
pointList2.add(new Point(3, 7));
Collections.sort(pointList2, myComparator); // myComparator에 선언한대로 정렬
for (Point i : pointList2) {
System.out.print(" X : "+ i.getX() + " Y : "+ i.getY());
System.out.println();
}
// 참고 Arrays.sort()와 Collections.sort()의 차이
// Arrays.sort() 배열 정렬의 경우 vs Collections.sort() List Collection 정렬의 경우
}
}
Arrays.sort(배열)을 이용해 오름차순 정렬을 할 수 있습니다.
Arrays.sort(arr1)
또한 String 타입의 배열또한 오름차순 정렬을 할 수 있습니다. (알파벳 A부터 시작 정렬)
Arrays.sort(arr2)
Arrays.sort(배열,Collections.reverseOrder())을 이용해 내림차순 정리할 수 있습니다.
Arrays.sort(arr3,Collections.reverseOrder())
또한 String 타입의 배열또한 내림차순 정렬을 할 수 있습니다. (알파벳 Z부터 시작 정렬)
Arrays.sort(arr4,Collections.reverseOrder())
Arrays.sort(arr5, 인덱스, 인덱스끝)를 이용해 범위를 정해서 정렬할 수 있습니다. (인덱스 ~ 인덱스끝 -1 까지)
Arrays.sort(arr5, 0, 4)
객체도 정렬할 수 있는데 class People implements Comparable<People> {.... 와 같이
Comparable 또는Comparator를 사용해야 합니다.
Arrays.sort(배열)로 정렬이 가능한데 여기서 arr6에 해당하는 배열은 People이라는 객체를 의미합니다.
별반 다른 거 없어 보이는데 위에랑 People 클래스를 정의한 곳에 보면 CompareTo라는 것을 오버라이드했습니다.
객체 같은 특별한 거라든가 내가 원하는대로 커스터마이징 하고 싶은 경우에는 오버라이드해서 적용시켜야합니다.
public int compareTo(People people) {
if (this.age < people.age) {
return -1;
} else if (this.age == people.age) {
return 0;
} else {
return 1;
}
}
compareTo라는 함수를 알아봐야하는데 어떤 함수냐면 말 그대로 비교하는 함수입니다.
현재 객체 < 인자로 넘어온 객체(여기선people) : return 음수
현재 객체 == 인자로 넘어온 객체(여기선people) : return 0
현재 객체 > 인자로 넘어온 객체(여기선people) : return 양수 입니다.
그런데 이렇게 return만 있으면 뭐 어떻게 작성해야할지도 모르잖아요 더 자세히 알아보면
음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우에는 두 객체의 자리가 바뀝니다.
this.age < people.age을 보면 현재 객체의 나이와 인자값 people의 나이를 비교해서
people의 나이가 더 크면-1 즉 그대로 유지됩니다.
같을 경우도 0을 반환함으로써 자리가 그대로 유지 됩니다.
그렇지 않은 경우는 1을 반환합니다. 두 객체의 자리가 바뀌죠
이 맥락으로 봤을 때 이렇게 만든 사람의 의도는 나이를 비교해서 오름차순으로 정리하는 걸 알 수 있습니다.
예시를 들어서 people 객체의 이름은 무시하고 age가 6 4 이면 6하고 4을 비교하죠? 그러면 6 < 4 이기 때문에
1을 반환합니다. 그러면 자리가 바뀌어서 4 6이 되죠 오름차순으로 정렬 되었죠?
Arrays.sort(배열,Collections.reverseOrder()) 을 이용해 내림차순 정렬을 할 수 있습니다.
Arrays.sort(arr6,Collections.reverseOrder())
List<Point> pointList = new ArrayList<Point>() 같이 Point객체를 받는 ArrayList여도 똑같이 정렬이 가능합니다.
Collections.sort(ArrayList객체명)
Collections.sort(pointList) 하지만 조금 다른 점이 있는데 Arrays를 사용 안 하고 Collections를 써야합니다.
(ArrayList때문에) 또한 Point객체를 이용하는 경우 Point클래스에 CompareTo를 구현해야합니다.
Comparator<Point> myComparator = new Comparator<Point>() {
@Override
public int compare(Point p1, Point p2) {
if (p1.x > p2.x) {
return 1; // x에 대해서는 오름차순
}
else if (p1.x == p2.x) {
if (p1.y < p2.y) { // y에 대해서는 내림차순
return 1;
}
}
return -1;
}
};
또 다른 객체 비교하는 클래스가 있는데 그게 Comparator입니다.
사용 방법은 Comparator<클래스명> 객체명 = new Comparator<클래스명>()
Comparator<Point> myComparator = new Comparator<Point>()
그 후 Comparable이 CompareTo를 구현한 거처럼 compare(인자값1, 인자값2)으로 오버라이드 해야합니다.
구현 방법은 위에 설명한 것과 동일합니다.
Collections.sort(배열명, Comparator클래스를 이용해 만든 객체명)으로
배열에 내가 정의한 compare메소드가 들어있는 객체를 적용시키는 것입니다.
Collections.sort(pointList2, myComparator)
그러면 Comparable과 Comparator는 무슨 차이가 있나요? 그걸 알아봅시다.
1번 Comparable을 사용하고자 한다면 compareTo 메소드를 오버라이드해야합니다.
그리고 Comparable은 인터페이스입니다. 그리고 자기 자신과 인자값 한개를 비교하죠
2번은 Comparator의 경우 클래스이며 compare 메소드를 오버라이드를 해야합니다 그리고
두개의 매개변수를 받아서 그 두개를 비교하죠
결과적으로 이런 차이만 있을 뿐 객체를 비교하기 위해 있다는 건 동일합니다.