코딩테스트 문제를 풀다 보면 컬렉션을 여러 기준으로 정렬할 일이 많이 생긴다.
그 방법을 알아보자.
자바 공식 문서 Comparable
compareTo(T o) 매서드 하나가 선언되어 있다.
자바 공식 문서 Comparator
compare(T o1, T o2) 매서드를 오버라이딩 하면 된다.
이 인터페이스들은 이름과 같이 객체를 비교하는 기능을 가진 인터페이스이다. 클래스에는 여러 필드가 있다. 이 클래스를 대소비교를 한다고 하면 어떤 기준으로 해야 하는지 모호하다.
따라서, 이 인터페이스를 사용함으로써 객체의 대소비교가 가능해진다.
- Comparable(T o) : 파라미터로 받은 객체와 자신을 비교
- Comparator(T o1, T o2) : 파라미터로 받은 두 객체를 비교
단어 하나 당 담겨야 하는 정보는 "단어, 등장 횟수" 이다. 그래서 클래스를 만들었다.
public static class Word implements Comparable<Word>{
String name;
int cnt;
//
public Word(String name) {
this.name = name;
cnt = 1;
}
이제 자주 나오는 순, 길이가 긴 순, 알파벳 사전 순 으로 정렬을 해야 한다.
public static class Word implements Comparable<Word>{
String name;
int cnt;
public Word(String name) {
this.name = name;
cnt = 1;
}
@Override
public int compareTo(final Word o) {
if(this.cnt != o.cnt){
if(this.cnt > o.cnt) return -1;
else if(this.cnt == o.cnt) return 0;
else return 1;
}
if(this.name.length() != o.name.length()){
if(this.name.length() > o.name.length()) return -1;
else if(this.name.length() == o.name.length()) return 0;
else return 1;
}
return this.name.compareTo(o.name); //String.class의 compareTo() 매개변수가 사전순 앞에 있으면 1
}
Collections.sort(list, new Comparator<Word>() {
@Override
public int compare(Word o1, Word o2) {
if(o1.cnt != o2.cnt){
if(o1.cnt > o2.cnt) return -1;
else if(o1.cnt == o2.cnt) return 0;
else return 1;
}
if(o1.name.length() != o2.name.length()){
if(o1.name.length() > o2.name.length()) return -1;
else if(o1.name.length() == o2.name.length()) return 0;
else return 1;
}
return o1.name.compareTo(o2.name); //String.class의 compareTo() 매개변수가 사전순 앞에 있으면 1
}
});
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static class Word{
String name;
int cnt;
public Word(String name) {
this.name = name;
cnt = 1;
}
// @Override
// public int compareTo(final Word o) {
//
// if(this.cnt != o.cnt){
// if(this.cnt > o.cnt) return -1;
// else if(this.cnt == o.cnt) return 0;
// else return 1;
// }
// if(this.name.length() != o.name.length()){
// if(this.name.length() > o.name.length()) return -1;
// else if(this.name.length() == o.name.length()) return 0;
// else return 1;
// }
// return this.name.compareTo(o.name); //String.class의 compareTo() 매개변수가 사전순 앞에 있으면 1
// }
}
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine());
int n = Integer.parseInt(stringTokenizer.nextToken());
int wordSize = Integer.parseInt(stringTokenizer.nextToken());
Map<String, Word> map = new HashMap<>();
List<Word> list = new ArrayList<>();
for(int i = 0; i < n; i++){
String str = bufferedReader.readLine();
if(str.length() < wordSize) continue;
if(map.containsKey(str)){
map.get(str).cnt++;
}
else{
Word word = new Word(str);
map.put(str, word);
list.add(word);
}
}
Collections.sort(list, new Comparator<Word>() {
@Override
public int compare(Word o1, Word o2) {
if(o1.cnt != o2.cnt){
if(o1.cnt > o2.cnt) return -1;
else if(o1.cnt == o2.cnt) return 0;
else return 1;
}
if(o1.name.length() != o2.name.length()){
if(o1.name.length() > o2.name.length()) return -1;
else if(o1.name.length() == o2.name.length()) return 0;
else return 1;
}
return o1.name.compareTo(o2.name); //String.class의 compareTo() 매개변수가 사전순 앞에 있으면 1
}
});
StringBuilder stringBuilder = new StringBuilder("");
for(Word word : list){
stringBuilder.append(word.name);
stringBuilder.append("\n");
}
System.out.println(stringBuilder.toString());
}
}