[Java] Collection.sort, comperator, Map의 정렬
//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 9 8 7 6 5 4 3 2 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다
나는 오름차순을 만들고 싶어
그렇다면 지금 이 순서를 유지해야겠지, 순서를 유지한다? -> 위치를 변경시키지않는다-> 음수를 내보낸다.
나는 내림차순을 만들고싶어
그렇다면 지금 순서를 바꿔야겠지, 순서를 바꾼다-> 위치를 변경시킨다->양수를 내보낸다.
자바 문자열 비교 함수 compare(), compareTo()
compareTo() : 문자열의 사전순 값을 비교하여 그에 해당되는 int 값을 리턴한다. 예로 A > B 라고 가정하면, - A = A = 0 (동일한 경우) - A > B = 1 (좌측 값이 큰 경우) - B > A = -1 (좌측 값이 작은 경우) 예..
lookingfor.tistory.com
https://st-lab.tistory.com/243
//왜 o1-o2를 하면 오버플로우가 날 수 있으니 주의해야하는지 써있음
자바 [JAVA] - Comparable 과 Comparator의 이해
아마 이 글을 찾아 오신 분들 대개는 Comparable과 Comparator의 차이가 무엇인지 모르거나 궁금해서 찾아오셨을 것이다. 사실 알고보면 두 개는 그렇게 어렵지 않으나 아무래도 자바를 학습하면서 객
st-lab.tistory.com
https://loosie.tistory.com/429
[프로그래머스] 2019 카카오 블라인드 #2 실패율 (Java)
#2 실패율 난이도 : LEVEL 1 유형 : 자료구조 코딩테스트 연습 - 실패율 실패율 슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의
loosie.tistory.com
https://cornswrold.tistory.com/114
[JAVA] Map에 있는 데이터를 Value기준으로 정렬하기
Map의 Value데이터 기준으로 정렬하기 TreeSet을 이용하면 Key 기준으로 쉽게 정렬할 수 있으나, Value로 정렬해주는 컬렉션은 존재하지 않는다. Value로 map을 정렬을 하려면 Comparator 인터페이스를 이용
cornswrold.tistory.com
https://www.youtube.com/watch?v=EW3Mub24wYg
https://www.youtube.com/watch?v=u0pJGFyvrqc