티스토리 뷰

List의 제네릭 타입이 기본형 혹은 String 일 땐 Collections.sort(List<?> list) 메서드를 사용하면 간단하게 해결된다. 하지만 제네릭 타입에 컬렉션이 출동하면 어떨까? 컬!렉!션!

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<StringString> map = new HashMap<StringString>();
        
        ArrayList<HashMap<StringString>> list = new ArrayList<HashMap<String,String>>();
        map.put("no""3");
        map.put("title""test3");
        list.add(map);
        map = new HashMap<StringString>();
        map.put("no""1");
        map.put("title""test1");
        list.add(map);
        map = new HashMap<StringString>();
        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<StringString>> {
 
    private final String key;
    
    public MapComparator(String key) {
        this.key = key;
    }
    
    @Override
    public int compare(HashMap<StringString> first, HashMap<StringString> 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}]
cs

Collections.sort() 메서드에 인터페이스 Comparator를 implement하는 클래스를 인자값으로 추가한다. 여기서 MapComparator 클래스를 살펴보면 해쉬맵에서 키에 대응하는 값을 가져오기 위해 생성자블럭으로 키값을 받아 처리하게 해놨다. 오버라이드 메서드인 compare()는 int형 결과를 리턴하며 이는 Collections.sort() 메서드에서 사용된다.

그런데 이 MapComparator 클래스는 정렬을 위한 용도 외에는 사용되지 않을것이다. 이처럼 단 한번만 사용되며 다른곳에서 가져다 쓸 계획이 없는 클래스라면 다음처럼 중첩 클래스로 구현하는 방법을 추천한다. 

public class Test {
    public static void main(String[] args) throws Exception {
        HashMap<StringString> map = new HashMap<StringString>();
        
        ArrayList<HashMap<StringString>> list = new ArrayList<HashMap<String,String>>();
        map.put("no""3");
        map.put("title""test3");
        list.add(map);
        map = new HashMap<StringString>();
        map.put("no""1");
        map.put("title""test1");
        list.add(map);
        map = new HashMap<StringString>();
        map.put("no""2");
        map.put("title""test2");
        list.add(map);
        System.out.println(list);
        
        Collections.sort(list, new Comparator<HashMap<StringString >>() {
            @Override
            public int compare(HashMap<StringString> first,
                    HashMap<StringString> second) {
                
                return first.get("no").compareTo(second.get("no"));
            }
        });
 
        System.out.println(list);
    }
}
cs

인터페이스 작성을 생략하기 위한 익명-중첩 클래스 형식의 코드지만 핵심은 첫번째 예시와 크게 다르지 않다.

마지막으로 위 예시들은 모두 오름차순 정렬이며 내림차순 정렬은 return 값을 수정하는 것으로 구현할 수 있다. Comparator 인터페이스를 implements 하며 compare() 메서드를 오버라이드 한 뒤  두 값 중 앞의 것이 크면 -1, 같으면 0, 뒤의 것이 크면 1을 리턴시켜준다.1

   Collections.sort(list, new Comparator<HashMap<StringString >>() {
        @Override
        public int compare(HashMap<StringString> first,
                HashMap<StringString> 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;
            }
        }
    });
cs


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;
        }
    }
});
cs


  1. 오름차순은 이의 반대다. 앞의 것이 크면 1 뒤의 것이 크면 -1


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함