一个更为强大的Comparator,可以说再也不用写侵入式的Comparable接口,而且连Comparator的lambda都可以不写了。
我先来看需要排序的类:
public class Person {
public enum Sex {
MALE, FEMALE
}
private String name;
private LocalDate birthday;
private Sex gender;
private String emailAddress;
Person(String nameArg, LocalDate birthdayArg,
Sex genderArg, String emailArg) {
name = nameArg;
birthday = birthdayArg;
gender = genderArg;
emailAddress = emailArg;
}
public int getAge() {
return birthday
.until(IsoChronology.INSTANCE.dateNow())
.getYears();
}
public void printPerson() {
System.out.println(name + ", " + this.getAge());
}
public Sex getGender() {
return gender;
}
public String getName() {
return name;
}
public String getEmailAddress() {
return emailAddress;
}
public LocalDate getBirthday() {
return birthday;
}
public static List<Person> createRoster() {
List<Person> roster = new ArrayList<>();
roster.add(
new Person(
"Bob",
IsoChronology.INSTANCE.date(2000, 9, 12),
Person.Sex.MALE, "bob@example.com"));
roster.add(
new Person(
"Fred",
IsoChronology.INSTANCE.date(1980, 6, 20),
Person.Sex.MALE,
"fred@example.com"));
roster.add(
new Person(
"Jane",
IsoChronology.INSTANCE.date(1990, 7, 15),
Person.Sex.FEMALE, "jane@example.com"));
roster.add(
new Person(
"George",
IsoChronology.INSTANCE.date(1990, 7, 15),
Person.Sex.MALE, "george@example.com"));
return roster;
}
}
编写一个测试类,并初始化数据
public class ComparotorTest {
private static List<Person> roster;
@BeforeClass
public static void setup() {
roster = Person.createRoster();
for (Person p : roster) {
p.printPerson();
}
}
}
对Person的单个字段进行排序
@Test
public void testWithComparing() {
System.out.println("Comparator.comparing");
roster.sort(Comparator.comparing(Person::getBirthday));
roster.stream().forEach(person -> person.printPerson());
}
对Person的多个字段进行排序
@Test
public void testWithComparing() {
System.out.println("Comparator.comparing");
roster.sort(Comparator.comparing(Person::getBirthday).thenComparing(Person::getName));
roster.stream().forEach(person -> person.printPerson());
}
对其中的某个字段倒序
@Test
public void testWithComparing() {
System.out.println("Comparator.comparing");
roster.sort(Comparator.comparing(Person::getBirthday).reversed().thenComparing(Person::getName));
roster.stream().forEach(person -> person.printPerson());
}
让其中的一个字段为空的时候放在前面或者后面
@Test
public void testWithComparing() {
System.out.println("Comparator.comparing");
roster.sort(Comparator.comparing(Person::getBirthday,Comparator.nullsLast(Comparator.reverseOrder())).thenComparing(Person::getName));
roster.stream().forEach(person -> person.printPerson());
}