Guava의 Ordering을 이용하여 리스트의 내용을 정렬한다.

List<Integer> list = Arrays.asList(10, 5, 0, 100, -1);
Collections.sort(list, Ordering.natural());
System.out.println(list);


결과 

[-1, 0, 5, 10, 100]



리스트의 내용을 역순으로 정렬한다.

List<Integer> list = Arrays.asList(10, 5, 0, 100, -1);
Collections.sort(list, Ordering.natural().reverse());
System.out.println(list);


결과

[100, 10, 5, 0, -1]




엘리먼트에 null이 추가되어 있으면, NPE가 발생한다. NPE도 발생하지 않고 null을 앞으로 둘지, 앞으로 둘지 결정할 수 있다.


List<Integer> list = Arrays.asList(10, 5, 0, null, 100, -1);
Collections.sort(list, Ordering.natural().nullsLast());
System.out.println(list);

결과

[-1, 0, 5, 10, 100, null]



List<Integer> list = Arrays.asList(10, 5, 0, null, 100, -1);
Collections.sort(list, Ordering.natural().nullsFirst());
System.out.println(list);


결과

[null, -1, 0, 5, 10, 100]




길이로 정렬하는 코드이다. Ordering을 상속하여 Collections.sort에 적용한다.

class CustomOrdering extends Ordering<String> {
@Override
public int compare(String s1, String s2) {
return Ints.compare(s1.length(), s2.length());
}
}
List<String> list = Arrays.asList("zzzzzz", "xxxx", "yyy", "aa", "b");
Ordering<String> customOrdering = new CustomOrdering();
Collections.sort(list, customOrdering);
System.out.println(list);


결과

[b, aa, yyy, xxxx, zzzzzz]



2 번 정렬하는 것을 만든다. 첫 번째는 문자열 정렬, 두 번째는 CustomOrdering 정렬을 사용하도록 한다.


class CustomOrdering extends Ordering<String> {
@Override
public int compare(String s1, String s2) {
return Ints.compare(s1.length(), s2.length());
}
}
List<String> list = Arrays.asList("zzzzzz", "xxxx", "yyy", "aa", "aaa", "b", "bb");
Ordering<String> customOrdering = new CustomOrdering();
Collections.sort(list, Ordering.natural().compound(customOrdering));
System.out.println(list);


결과는 다음과 같다. 

[aa, aaa, b, bb, xxxx, yyy, zzzzzz]



Guava의 Ordering 메소드, natural(), usingToString(), arbitary()를 비교했다. 

List<String> list = Arrays.asList("arth", "samuel", "jonathan", "flynn", "zax", "kang");

System.out.println("original:" + list);
System.out.println("naturalOrdering:" + Ordering.natural().sortedCopy(list));
System.out.println("usingToStringOrdering:" + Ordering.usingToString().sortedCopy(list));
System.out.println("arbitraryOrdering:" + Ordering.arbitrary().sortedCopy(list));



결과

original:[arth, samuel, jonathan, flynn, zax, kang]

naturalOrdering:[arth, flynn, jonathan, kang, samuel, zax]

usingToStringOrdering:[arth, flynn, jonathan, kang, samuel, zax]

arbitraryOrdering:[flynn, arth, kang, zax, samuel, jonathan]



usingToString()은 문자열에서는 잘 비교하기 어렵다. 숫자일 때 비교하기 쉽다.


List<Integer> list =  Arrays.asList(1, 100, 11, 10, 20, 1000, 2, 22);
System.out.println("original:" + list);
System.out.println("naturalOrdering:" + Ordering.usingToString().sortedCopy(list));


결과

original:[1, 100, 11, 10, 20, 1000, 2, 22]

naturalOrdering:[1, 10, 100, 1000, 11, 2, 20, 22]





Ordering 클래스의 api를 테스트한 코드이다. min/max, leastOf, greatestOf 메소드가 존재한다.


List<Integer> list = Arrays.asList(10, 20, 15, 13, 8, 17, 4);

Ordering<Integer> naturalOrdering = Ordering.natural();
System.out.println("natural:" + list);
System.out.println("before sorting, isOrdered:" + naturalOrdering.isOrdered(list));
Collections.sort(list, naturalOrdering);
System.out.println("natural Ordering:" + list);
System.out.println("after sorting, isOrdered:" + naturalOrdering.isOrdered(list));
System.out.println("after sorting, isStrictlyOrdered:" + naturalOrdering.isStrictlyOrdered(list));

System.out.println("after sorting, max:" + naturalOrdering.max(list));
System.out.println("after sorting, min:" + naturalOrdering.min(list));

System.out.println("leastOf list:" + naturalOrdering.leastOf(list, 3));
System.out.println("greatestOf list:" + naturalOrdering.greatestOf(list, 3));


결과


natural:[10, 20, 15, 13, 8, 17, 4]

before sorting, isOrdered:false

natural Ordering:[4, 8, 10, 13, 15, 17, 20]

after sorting, isOrdered:true

after sorting, isStrictlyOrdered:true

after sorting, max:20

after sorting, min:4

leastOf list:[4, 8, 10]

greatestOf list:[20, 17, 15]




onResultOf() 테스트 코드이다. 숫자를 문자열 기준으로 정렬하는 예시이다.



List<Integer> toSort = Arrays.
asList(1, 100, 11, 10, 20, 1000, 2, 22);
Ordering<Object> ordering = Ordering.natural().onResultOf(Functions.toStringFunction());
System.out.println(ordering.sortedCopy(toSort));


결과

[1, 10, 100, 1000, 11, 2, 20, 22]



onResult()와 compound() 메소드와 Member 객체를 이용해서 2 번을 정렬한다.


public static String getDisplayName(String name, String familyName) {
if (familyName != null && name != null) {
return familyName + name;
}
return familyName;
}

class Member {
public String id;
public String name;
public String familyName;
public boolean favorite;

public Member(String id, String name, String familyName, boolean favorite) {
this.id = id;
this.name = name;
this.familyName = familyName;
this.favorite = favorite;
}

public String toString() {
return "id:" + id + ",name=" + name + ",familyName="+ familyName + ",favorite:" + favorite;
}
111

먼저 Member의 favorite을 기준으로 크게 나눠 정렬하고, 다음은 이름으로 정렬한다.
 

Member member0 = new Member("100", "samuel", "kim", true); Member member1 = new Member("101", "flynn", "park", true);
Member member2 = new Member("102", "jonathan", "boung", true);
Member member3 = new Member("103", "jaxson", "carl", false);
Member member4 = new Member("103", "brayan", "arth", false);
List<Member> members = Arrays.asList(member0, member1, member2, member3, member4);

Ordering<Member> byFavorite = Ordering.natural().onResultOf(new Function<Member, Comparable>() {
@Override
public Boolean apply(Member profile) {
return profile.favorite;
}
}).reverse();

Ordering<Member> byDisplayName = Ordering.natural().onResultOf(new Function<Member, String>() {
@Override
public String apply(Member member) {
return getDisplayName(member.name, member.familyName);
}
});

List<Member> sortedProfiles = byFavorite.compound(byDisplayName).immutableSortedCopy(members);

System.out.println(sortedProfiles);


결과(의도대로 잘 나옴)


[id:102,name=jonathan,familyName=boung,favorite:true,
id:100,name=samuel,familyName=kim,favorite:true, 

id:101,name=flynn,familyName=park,favorite:true, 

id:103,name=brayan,familyName=arth,favorite:false, 

id:103,name=jaxson,familyName=carl,favorite:false]





Posted by '김용환'
,