我创建了一个不会抛出NPE的比较器。但是,在compareTo中使用它时,它将引发NPE。为什么?
public class Person implements Comparable<Person> {
public static final Comparator<Person> BIRTHDATE_ASCENDING_NULLS_FIRST = Comparator
.nullsFirst(Comparator.comparing(Person::getBirthDate,Comparator.nullsFirst(Comparator.naturalOrder())));
private String name;
private LocalDate birthDate;
public Person() {
super();
}
public Person(String name,LocalDate birthDate) {
this();
this.name = name;
this.birthDate = birthDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
@Override
public String toString() {
return name + " was born on " + (birthDate == null ? "???" : birthDate);
}
@Override
public int compareTo(Person other) {
// BEGIN ADITIONAL TESTS
if (other == null) {
return 1;
} else if (getBirthDate() == null ^ other.getBirthDate() == null) {
// nulls first
return getBirthDate() == null ? -1 : 1;
} else if (getBirthDate() == null) {
// both are null
return 0;
}
System.out.println(this.toString() + "," + other.toString());
// END ADITIONAL TESTS
return BIRTHDATE_ASCENDING_NULLS_FIRST.compare(this,other);
}
@Override
public int hashCode() {
int result = 1;
result = 31 * result + (birthDate == null ? System.identityHashCode(this) : birthDate.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getclass() != obj.getclass()) {
return false;
}
return Objects.equals(birthDate,((Person) obj).getBirthDate());
}
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(null);
people.add(new Person("John",null));
people.add(new Person("Mary",LocalDate.now().minusYears(20)));
people.add(new Person("George",LocalDate.now().minusYears(10)));
Collections.sort(people,BIRTHDATE_ASCENDING_NULLS_FIRST);
System.out.println(people);
Collections.sort(people);
System.out.println(people);
Collections.sort(people,BIRTHDATE_ASCENDING_NULLS_FIRST.reversed());
System.out.println(people);
// This one throws NPE
Collections.sort(people);
System.out.println(people);
}
在Collections.sort
调用中显露比较器时,排序操作未按预期使用compareTo
实现。
不执行此操作时,排序操作将使用compareTo
的实现。由于此方法调用的是完全相同的比较器,为什么在这里得到NPE?我的意思是,为什么从compareTo
调用比较器时,它不处理NPE?