优雅地比较对象
1/**
2 * Java 8 函数式接口{@link Comparator}配合
3 * {@link Function}可以简化传统比较器的编写:
4 *
5 * <pre>
6 * @Override
7 * public int compareTo(Person p) {
8 * int cmp = this.lastname.compareTo(p.lastname);
9 * if (cmp != 0) {
10 * return cmp;
11 * }
12 * cmp = this.firstname.compareTo(p.firstname);
13 * if (cmp != 0) {
14 * return cmp;
15 * }
16 * return Long.compare(this.zipcode, p.zipcode);
17 * }
18 * </pre>
19 *
20 * 可以简化为:
21 *
22 * <pre>
23 * @Override
24 * public int compareTo(Person p) {
25 * return Comparator
26 * .comparing((Function<Person, String>) p1 -> p1.lastname)
27 * .thenComparing(person -> person.firstname)
28 * .thenComparing(person -> person.zipcode)
29 * .compare(this, p);
30 * }
31 * </pre>
32 * <p>
33 * 此外,guava工具类{@link ComparisonChain}提供了更加易于理解和编写
34 * (Java 8的函数式接口不易理解和编写)的优化比较器的方法:
35 *
36 * <pre>
37 * @Override
38 * public int compareTo(Person p) {
39 * return ComparisonChain.start()
40 * .compare(this.lastname, p.lastname)
41 * .compare(this.firstname, p.firstname)
42 * .compare(this.zipcode, p.zipcode)
43 * .result();
44 * }
45 * </pre>
46 * <p>
47 * 这种“链式分格”的方法调用在许多优秀的框架中都能看到
48 *
49 * @author wangy
50 * @date 2021.01.26/0026 16:00
51 */
52public class CompareChain {
53
54 static class Person implements Comparable<Person> {
55 String ln;
56 String fn;
57 long zipcode;
58
59 public Person(String lastname, String firstname, long zipcode) {
60 this.ln = lastname;
61 this.fn = firstname;
62 this.zipcode = zipcode;
63 }
64
65 /**
66 * usage : a.compareTo(b)
67 *
68 * @param p object to compared
69 * @return
70 *
71 * <pre>
72 * a > b ==> positive value <br>
73 * a = b ==> 0 <br>
74 * a < b ==> negative value
75 * </pre>
76 */
77 @Override
78 public int compareTo(Person p) {
79
80 // the old way can be replaced by guava ComparisonChain
81
82 /*
83 * return ComparisonChain.start()
84 * .compare(this.ln, p.ln)
85 * .compare(this.fn, p.fn)
86 * .compare(this.zipcode, p.zipcode)
87 * .result();
88 */
89
90 // The java 8 also offer Functional Interface to do this
91 // But the usage of Function<T,U>
92 // is a little bit complicated to understand
93 return Comparator
94 .comparing(
95 (Function<Person, String>) person -> person.ln)
96 .thenComparing(person -> person.fn)
97 .thenComparing(person -> person.zipcode)
98 .compare(this, p);
99 }
100 }
101
102 public static void main(String[] args) {
103 System.out.println("a".compareTo("b")); // -1
104
105 Person p1 = new Person("steve", "jobs", 520000);
106 Person p2 = new Person("steve", "jobs", 510000);
107 Person p3 = new Person("steve", "jobs", 530000);
108 Person p4 = new Person("steve", "jobs", 520000);
109
110 System.out.printf("p1 compares to p2: %d\n", p1.compareTo(p2));
111 System.out.printf("p1 compares to p3: %d\n", p1.compareTo(p3));
112 System.out.printf("p1 compares to p4: %d\n", p1.compareTo(p4));
113
114 }
115}