//value 오름차순
//value가 같을때 key 오름차순
List<Integer> list = new ArrayList<>(res.keySet());
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
int cmp = Double.compare(res.get(o1), res.get(o2));
return cmp == 0 ? o1-o2 : cmp;
}
});
Collection.sort를 알기위한 배경지식을 공부했다.
먼저 Collections는 컬렌션을 위한 메소드를 제공한다.(정렬부터 시작해서 다양한 기능을 제공한다.)
Collection.sort( 대상, 기준 )을 넣는다.
기준은 기본값이 오름차순이다.
o1과 o2 를 비교해서
if(o1 > o2) return 1 (서로 위치바꿈, 바꾸는 식을 사용하기위해 1=true인듯)
if(o1 < o2) return -1 1 2 3 4 5 6 7 8 9 ( 기본이 오름차순이기 때문에 바꾸는식을 사용 안하기위해 -1=false인듯)
if(o1 = o2) return 0
(두 값이 같은 경우일때, 또 다른 기준을 적용하기 위해 존재하는 것 같음, 예를 들어 map을 value순으로 정렬하되 같을 경우 key를 내림차순으로 정렬해라 같은 기준을 말하는것
예를 들어 Map의 key:1 value :10, key:3 value:10으로 정렬되있을 때 key : 3 key: 1순으로 정렬하기위해 0이라는 기준이 필요함)
collection의 map의 기준
Map또한 기본이 오름차순인것 같음
value는 기본이 오름차순이고
Map의 value가 같다면 key를 오름차순으로 정렬함
if( key1 > key2) return 1 이기때문에 서로 위치를 바꾸는 식이 사용함
if( key1 < key2) return -1 이기때문에 서로 위치를 바꾸는 식이 사용되지 않음
if(key = key) =0 서로 같을때 새로운 기준을 정하기 위해 존재함
Map
key : 5, value 8
key : 3, value 5
key : 1, value 8
key : 2, value 4
의 Map을 value로 오름차순으로 정렬한다면
key : 2, value 4
key : 3, value 5
로 정렬되다가
key : 1, value 8 == key : 5, value 8 value가 같기때문에0이고
0일때
if( key1 > key2) return 1 이기때문에 서로 위치를 바꾸는 식이 사용함
if( key1 < key2) return -1 이기때문에 서로 위치를 바꾸는 식이 사용되지 않음
if(key = key) =0 서로 같을때 새로운 기준을 정하기 위해 존재함
의 규칙이 적용되어 key도 오름차순으로 정렬됨
따라서 이런 식으로 정렬할 수 있음
//value를 내림차순
//value가 같을때 key를 오름차순
List<Integer> list = new ArrayList<>(res.keySet());
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//위에서 말했듯 기본값이 오름차순임
//return으로 1이나오면 res.get(o1)과 res.get(o2)를 서로 바꾸는거임 res.get(o1) res.get(o2)였다면 o2 o1으로
//o1 < o2일때만 서로의 위치를 바꾸는 식을 적용시켜주지않겠다는것(버블정렬을 사용하는듯)
//Double.compare(res.get(o1), res.get(o2))을 했을때
//res.get(o1) < res.get(o2)이라면 -1의 값이나옴 따라서 서로의 위치를 바꾸는 식이 적용안됨
//즉 res.get(o1) < res.get(o2)가 아니면 위치바꾸겠다는것 오름차순만 인정하겠다는것
//내림차순을 하고 싶다면?
//Double.compare(res.get(o1), res.get(o2))을 했을때
//res.get(o2) > res.get(o1)일때 1임, 이 값을 -1로 만들어주는거임
//즉 res.get(o2) > res.get(o1)일때만 서로의 위치를 바꾸는 식을 적용시키지 않겠다는것
int cmp = Double.compare(res.get(o1), res.get(o2))*(-1);
//value의 값이 같을때 기준을 만드는 것임 res.get(o1) == res.get(o1)이라면
//바꾸는 식을 어떻게 적용할까를 만들어 줄 수 있음
//아무것도 적지 않으면 o1 < o2 일때 -1로 처리하는 것같음
//반복하지만 당연히 o1 > o2 일때는 = 1, o1 = o2 일때는 0 (여기서 map의 key라 당연히 0일 수가 없겠지만..key는 중복될 수 없으니까)
//따라서 여기서 key는 Integer니까 빼서 조건을 알려주는거임, 밑의 강의 처럼 삼항연산자로처리해도
상관없음 중요한건 결과적으로 1,-1,0 어떤게 나가는가임
//우리가 원하는건 key의 오름차순임
//즉 o1 < o2여야 한다는것,
//key1=1, key2=2이며
//value(key1) = value(key2)이고
//Map에
//비교하는 순간 [key1=1, value] ,[key2 = 2, value] 순서로 저장되어있다면 위치를 안바꾸겠다는 것임
//즉 저 순서인 상태에서 안 바꾸고 싶다 -> 바꾸는 식을 쓰기 싫다 -> -1을 내놔라임
//그렇다면 key가 오름차순으로 하기위해서는? keys = {1,2,3,4,5,6,7} 같이 되어야한다는것
//key1 < key2이면 바꾸지말라는것
// A < B인 경우는? A-B인경우, Integer.compare(o1,o2) = -1인 경우이다.
//(참고:compare에서 -3,-4로 나가도 상관없는것 같다. 중요한것 양수냐 음수냐 0이냐다.
//어처피 밖에서 compare>0, compare<0, compare==0의 조건으로 처리되는것 같다.)
//즉 return이 의미하는것은
//비교했는데 0이야? 같아? 그러면 key끼리 비교해봐
//key1 < key2인 상태야? 오케이, 바꾸는 식 쓰지마 -1가지고 나가
//key > key2인 상태야? 안돼, 바꾸는 식 써 1가지고 나가
//인 뜻인거다.
return cmp == 0 ? Integer.compare(o1,o2) : cmp;
}
});
이러한 기본 개념을 알았다면 이제는 여러가지 방법을 구현할 수가 있다.
//value 내림차순
//value가 같을때 key 오름차순
List<Integer> list = new ArrayList<>(res.keySet());
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
int cmp = Double.compare(res.get(o2), res.get(o1));
//int cmp = Double.compare(res.get(o1), res.get(o2))*(-1);
//cmp = res.get(o2) - res.get(o1) //로 해도 되지만 오버플로우가 발생하면 오류나니 주의
return cmp == 0 ? Integer.compare(o1,o2) : cmp;
//return cmp == 0 ? Integer.compare(o1,o2) : cmp;
//return cmp == 0 ? o1-o2 : cmp;
}
});
----------------------------------------------------------------------------------
//value 내림차순
//value가 같을때 key 내림차순
List<Integer> list = new ArrayList<>(res.keySet());
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
int cmp = Double.compare(res.get(o2), res.get(o1));
//int cmp = Double.compare(res.get(o1), res.get(o2))*(-1);
//cmp = res.get(o2) - res.get(o1) //로 해도 되지만 오버플로우가 발생하면 오류나니 주의
return cmp == 0 ? Integer.compare(o2,o1) : cmp;
//return cmp == 0 ? Integer.compare(o1,o2)*(-1) : cmp;
//return cmp == 0 ? o2-o1 : cmp; //오버플로우나면 오류나니 주의 o1 > o2일때 음수
}
});
----------------------------------------------------------------------------------
//value 오름차순
//value가 같을때 key 오름차순
//기본값이 value가 같을때 key는 오름차순이기때문에
//굳이 return cmp == 0 ? Integer.compare(o1,o2) : cmp; 을 쓸필요는 없음
//return Double.compare(res.get(o1), res.get(o2));만 해줘도 충분함
List<Integer> list = new ArrayList<>(res.keySet());
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
int cmp = Double.compare(res.get(o1), res.get(o2));
//cmp = res.get(o1) - res.get(o2) //로 해도 되지만 오버플로우가 발생하면 오류나니 주의
return cmp == 0 ? Integer.compare(o1,o2) : cmp;
//return cmp == 0 ? o1-o2 : cmp; //오버플로우나면 오류나니 주의
}
});
-----------------------------------------------------------------------------------
//value 오름차순
//value가 같을때 key 내림차순
List<Integer> list = new ArrayList<>(res.keySet());
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
int cmp = Double.compare(res.get(o1), res.get(o2));
//cmp = res.get(o1) - res.get(o2) //로 해도 되지만 오버플로우가 발생하면 오류나니 주의
return cmp == 0 ? Integer.compare(o1,o2)*(-1) : cmp;
//return cmp == 0 ? Integer.compare(o2,o1) : cmp;
//return cmp == 0 ? o2-o1 : cmp; //오버플로우나면 오류나니 주의 o1 > o2일때 음수
}
});
즉 중요한건 compare에서 나가는게 음수냐 양수냐임
o1은 now라 생각하고 o2 next라고 생각하면 이해가 쉬워짐
현재 값이 1이고 비교하는 값이 2다 (정렬은 버블정렬을 통해서 배열을 정렬을 한다는 것 같다. 버블 정렬은 밑의 글을 참고하면 좋을 것 같다) https://gmlwjd9405.github.io/2018/05/06/algorithm-bubble-sort.html
나는 오름차순을 만들고 싶어
그렇다면 지금 이 순서를 유지해야겠지, 순서를 유지한다?
-> 위치를 변경시키지않는다-
> 음수를 내보낸다.(public int copare(Integer o1, Integer o2)
나는 내림차순을 만들고싶어
그렇다면 지금 순서를 바꿔야겠지,
순서를 바꾼다-> 위치를 변경시킨다->양수를 내보낸다.
--------------------------------------------------Collection.sort를 이해하기 위해 좋은 글들-------------------------------------------------------
https://st-lab.tistory.com/243
//왜 o1-o2를 하면 오버플로우가 날 수 있으니 주의해야하는지 써있음
https://loosie.tistory.com/429
https://cornswrold.tistory.com/114
https://www.youtube.com/watch?v=EW3Mub24wYg
https://www.youtube.com/watch?v=u0pJGFyvrqc