示例:
package org.example.model;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.junit.Test;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
public class ComparisonChainTest {
@AllArgsConstructor
@Getter
public static class Person implements Comparable<Person> {
private String name;
private int age;
private String address;
@Override
public int compareTo(Person other) {
// 按名字倒序,年龄升序,地址为空的放最后排序
return ComparisonChain.start().compare(this.name, other.getName(), Ordering.natural().reversed())
.compare(this.age, other.getAge())
.compare(this.address, other.address, Ordering.natural().nullsLast())
.result();
}
}
@Test
public void test() {
// 1. 使用ComparisonChain实现Comparable接口,参考Person类
Person person1 = new Person("lisi", 20, "beijing");
Person person2 = new Person("lisi", 20, null);
Person person3 = new Person("zhangsan", 10, "nanjing");
assertThat(Lists.newArrayList(person2, person1, person3).stream().sorted().collect(Collectors.toList()))
.containsExactly(person3, person1, person2);
// 2. Ordering 实例是一个特殊的Comparator实例。
// Ordering把很多基于Comparator的静态方法(如Collections.max)包装为自己的实例方法(非静态方法),
// 并且提供了链式调用方法,来定制和增强现有的比较器,例如natural为自然排序(调用对象的Comparable接口),
// usingToString为使用对象的toString方法得到的字符串排序
assertThat(Ordering.from(Ints::compare).max(5, 6)).isEqualTo(6);
assertThat(Ordering.from(Ints::compare).min(5, 6)).isEqualTo(5);
assertThat(Ordering.natural().max(5, 6)).isEqualTo(6);
assertThat(Ordering.natural().min(5, 6)).isEqualTo(5);
List<Integer> list = Lists.newArrayList(5, 4, 3, 2, 1, null);
list.sort(Ordering.natural().nullsFirst()); // null放在前面
assertThat(list).containsExactly(null, 1, 2, 3, 4, 5);
list.sort(Ordering.natural().nullsLast()); // null放在后
assertThat(list).containsExactly(1, 2, 3, 4, 5, null);
}
}