[Java] 요소가 맵인 List 정렬하기
List의 구성요소를 정렬해야 할 때 구성요소의 타입이 기본형 혹은 String 일 땐 Collections.sort(List<?> list)
메서드를 사용하면 간단하게 해결된다. 하지만 요소가 String이 아닌 맵 타입이라면 어떻게 해야 할까?
ArrayList<HashMap<String, String>>
타입을 예로 들면:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
public class Test {
public static void main(String[] args) throws Exception {
HashMap<String, String> map = new HashMap<String, String>();
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
map.put("no", "3");
map.put("title", "test3");
list.add(map);
map = new HashMap<String, String>();
map.put("no", "1");
map.put("title", "test1");
list.add(map);
map = new HashMap<String, String>();
map.put("no", "2");
map.put("title", "test2");
list.add(map);
System.out.println(list);
MapComparator comp = new MapComparator("no");
Collections.sort(list, comp);
System.out.println(list);
}
}
class MapComparator implements Comparator<HashMap<String, String>> {
private final String key;
public MapComparator(String key) {
this.key = key;
}
@Override
public int compare(HashMap<String, String> first, HashMap<String, String> second) {
int result = first.get(key).compareTo(second.get(key));
return result;
}
}
// [{title=test3, no=3}, {title=test1, no=1}, {title=test2, no=2}]
// [{title=test1, no=1}, {title=test2, no=2}, {title=test3, no=3}]
Collections.sort()
메서드에 인터페이스 Comparator를 implement하는 클래스를 인자값으로 추가한다. 여기서 MapComparator 클래스를 살펴보면 해시맵에서 키에 대응하는 값을 가져오기 위해 생성자 블록으로 키 값을 받아 처리하게 해놨다. 오버라이드 메서드인 compare()
는 int형 결과를 반환하며 이는 Collections.sort()
메서드에서 사용된다.
public static void main(String[] args) throws Exception {
HashMap<String, String> map = new HashMap<String, String>();
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
map.put("no", "3");
map.put("title", "test3");
list.add(map);
map = new HashMap<String, String>();
map.put("no", "1");
map.put("title", "test1");
list.add(map);
map = new HashMap<String, String>();
map.put("no", "2");
map.put("title", "test2");
list.add(map);
System.out.println(list);
Collections.sort(list, new Comparator<HashMap<String, String>>() {
@Override
public int compare(HashMap<String, String> first,
HashMap<String, String> second) {
return first.get("no").compareTo(second.get("no"));
}
});
System.out.println(list);
}
인터페이스인 Comparator의 구현체 작성을 생략하기 위한 익명-중첩 클래스 형식의 코드다. 작동방식은 첫 번째 예시와 같다.
위의 예시들은 모두 오름차순 정렬이며 내림차순 정렬은 return 값을 수정하는 것으로 구현할 수 있다. Comparator 인터페이스를 implements 하며 compare()
메서드를 오버라이드 한 뒤 두 값 중 앞의 것이 크면 -1, 같으면 0, 뒤의 것이 크면 1을 반환한다. (오름차순은 이와 반대다. 앞의 것이 크면 1 뒤의 것이 크면 -1)
Collections.sort(list, new Comparator<HashMap<String, String>>() {
@Override
public int compare(HashMap<String, String> first,
HashMap<String, String> second) {
int firstValue = Integer.valueOf(first.get("no"));
int secondValue = Integer.valueOf(second.get("no"));
// 내림차순 정렬
if (firstValue > secondValue) {
return -1;
} else if (firstValue < secondValue) {
return 1;
} else /* if (firstValue == secondValue) */ {
return 0;
}
}
});
example
List<String>
내림차순 정렬
ArrayList<string> list = new ArrayList<string>();
// list.add....
// list.add....
Collections.sort(list, new Comparator<string>() {
@Override
public int compare(String o1, String o2) {
int firstValue = 0;
int secondValue = 0;
firstValue = (int) o1.charAt(0);
secondValue = (int) o2.charAt(0);
// 내림차순 정렬
if (firstValue > secondValue) {
return -1;
} else if (firstValue < secondValue) {
return 1;
} else /* if (firstValue == secondValue) */ {
return 0;
}
}
});