【发布时间】:2020-11-05 00:32:24
【问题描述】:
我创建了一个从不抛出 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?
【问题讨论】:
标签: java comparator comparable