JAVA List VO 정렬 Collections Sort Comparator 사용하기

2017. 9. 4. 18:29language/java


JAVA List VO 정렬 Collections Sort 사용하기

 

 

 

특정 vo 타입의 ArrayList 를 정렬해 보자.

 

기본적으로 배열을 정렬하는 방법은 많이 나와 있다.

 

하지만 객체를 담고있는 배열에 대해서 정렬하는 방법은 찾아보니 적당한 것이 없더라...

 

그래서 직접 만들어 보았다.

 

매우 피곤한 상태에서 만든거라 오류가 있을 수 있다...

 

 



 

list에 담고 있는 vo 객체의 getter 는 문자열일 수 도 있고 숫자일 수 도 있다.

 

그렇기 때문에 비교할 때 ASCII 코드를 활용해서 비교하도록 하였다.

 

테스트를 위한 VO를 하나 만들자.

 

SampleVO.java

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
32
public class SampleVO {
    private String name = "";
    private String age = "";
 
    /**
     * @return name
     */
    public String getName() {
        return name;
    }
 
    /**
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }
 
    /**
     * @return age
     */
    public String getAge() {
        return age;
    }
 
    /**
     * @param age
     */
    public void setAge(String age) {
        this.age = age;
    }
}
cs

평범한 vo 객체이다.


위 vo 객체를 List에 담자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
        List<SampleVO> sampleVOList = new ArrayList<SampleVO>();
 
        SampleVO sampleVO1 = new SampleVO();
        sampleVO1.setName("강호동");
        sampleVOList.add(sampleVO1);
        SampleVO sampleVO2 = new SampleVO();
        sampleVO2.setName("유재석");
        sampleVOList.add(sampleVO2);
        SampleVO sampleVO3 = new SampleVO();
        sampleVO3.setName("신동엽");
        sampleVOList.add(sampleVO3);
        SampleVO sampleVO4 = new SampleVO();
        sampleVO4.setName("김구라");
        sampleVOList.add(sampleVO4);
cs

간단하게 이름만 입력한 vo를 가지고 있는 list를 만들었다.

 

list를 출력해보자.

1
2
3
        for (SampleVO sampleVO : sampleVOList) {
            System.out.println(sampleVO.getName());
        }
cs

강호동
유재석
신동엽
김구라

 

콘솔창에 위와 같은 순서로 출력될 것이다.

 



 

이제 실제로 정렬을 하는 클래스를 구현해 보자.

클래스 명은 CompareListVO 로 정했다.

 

CompareListVO.java

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public class CompareListVO {
 
    /**
     * List<VO> 정렬
     *
     * @param list 비교할 리스트(List<VO> 만 가능)
     * @param getterMethodText 비교할 getter 함수
     * @param sortInfo 정렬 문자열 (ASC, DESC)
     */
    public static void sortListVO(List<?> list, String getterMethodText, String sortInfo) {
 
        Collections.sort(list, new Comparator<Object>() {
            @Override
            public int compare(Object firstObject, Object secondObject) {
                int rtn = 0;
                int compareIndex = 0// 비교 인덱스 (작은 문자열 수)
                String firstData = "";
                String secondData = "";
                int firstValue = 0;
                int secondValue = 0;
 
                // 비교할 대상
                try {
                    Method firstDeclaredMethod = firstObject.getClass().getDeclaredMethod(getterMethodText);
                    firstData = (String) firstDeclaredMethod.invoke(firstObject, new Object[] {});
                    Method secondDeclaredMethod = secondObject.getClass().getDeclaredMethod(getterMethodText);
                    secondData = (String) secondDeclaredMethod.invoke(secondObject, new Object[] {});
                } catch (NoSuchMethodException | SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
 
                if (firstData == null || firstData == "" || secondData == null || secondData == "") { return rtn; }
 
                // 기본 정렬값 설정
                if ("DESC".equals(sortInfo)) {
                    if (firstData.length() > secondData.length()) {
                        rtn = -1;
                        compareIndex = secondData.length();
                    } else if (firstData.length() < secondData.length()) {
                        rtn = 1;
                        compareIndex = firstData.length();
                    } else {
                        compareIndex = firstData.length();
                    }
                } else {
                    if (firstData.length() < secondData.length()) {
                        rtn = -1;
                        compareIndex = firstData.length();
                    } else if (firstData.length() > secondData.length()) {
                        rtn = 1;
                        compareIndex = secondData.length();
                    } else {
                        compareIndex = firstData.length();
                    }
                }
 
                for (int i = 0; i < compareIndex; i++) {
                    firstValue = Integer.valueOf(firstData.charAt(i));
                    secondValue = Integer.valueOf(secondData.charAt(i));
 
                    if ("DESC".equals(sortInfo)) {
                        if (firstValue > secondValue) {
                            rtn = -1;
                            break;
                        } else if (firstValue < secondValue) {
                            rtn = 1;
                            break;
                        }
                    } else {
                        if (firstValue < secondValue) {
                            rtn = -1;
                            break;
                        } else if (firstValue > secondValue) {
                            rtn = 1;
                            break;
                        }
                    }
                }
 
                return rtn;
            }
        });
    }
}
cs

 

간단하게 설명하자면 파라미터로 정렬할 대상의 List와 정렬에 사용할 getter 함수 문자열, 정렬정보를 받는다.


정렬에 사용할 getter 함수를 활용해서 변수의 값을 추출하고 1글자씩 아스키코드로 변환한 후 비교하게 된다.

 

사용방법은 다음과 같다.

 

1
CompareListVO.sortListVO(sampleVOList, "getName""ASC");
cs
1
CompareListVO.sortListVO(sampleVOList, "getName""DESC");
cs

 

업그레이드 시킨다면 정렬할 대상의 변수를 여러개 지정해 보는것도 가치가 있어 보인다.

 

또한 변수별로 정렬방법을 다르게 할 수 도 있을 것 같다.

 

위 소스를 활용해서 조금만 수정하면 List<Map> 타입의 Collection 도 정렬이 가능해 보인다.