使用 Comparable 在 Lambda 中处理 java 8 Collection Sort 方法中的空检查
Handling null checks in java 8 Collection Sort method within a Lambda using Comparable
我有一个 Member
的列表,如果我有空值,需要在 java 8 collection.sort 方法中对 Person
firstName 进行空检查处理。目前我有 Member
实现 Comparable
接口以便 compareTo
另一个成员的全名。我从 TimSort binarySort 得到一个 NullPointerException。好像是 bug in OpenJDK. Found a solution to the NullPointerException in this question。上述问题的任何推荐解决方案以及我在下面提到的内容。
主程序
import java.util.Collections;
import java.util.List;
public class SortMembersByFirstName {
public static void main(String[] args) {
List<Member> members = getMembers();
List<Member> sorted = setMemberCacheOrderByFirstName(members);
for (Member mem: sorted) {
System.out.println(mem.toString());
}
}
private static List<Member> getMembers() {
Person tim = new Person("Tim", "Southee");
Member member1 = new Member(tim);
Person eoin = new Person("Eoin", "Morgan");
Member member2 = new Member(eoin);
Person moeenAli = new Person("Moeen", "Ali");
Member member3 = new Member(moeenAli);
Person timFirstNameNull = new Person(null, "Tim");
Member member4 = new Member(timFirstNameNull);
Person timFirstNameLastNameNull = new Person(null, null);
Member member5 = new Member(timFirstNameLastNameNull);
Person nullPerson = null;
Member member6 = new Member(nullPerson);
List<Member> members = new ArrayList<>();
members.add(member1);
members.add(member2);
members.add(member3);
members.add(member4);
members.add(member5);
members.add(member6);
return members;
}
/**
* Order list members by first name
*/
private static List<Member> setMemberCacheOrderByFirstName(List<Member> members) {
// TimSort.binarySort NPE
Collections.sort(members, (m1, m2) ->
m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName())
);
return members;
}
}
会员class
class Member implements Comparable<Member>{
private Person person;
public Member(Person person){
this.person = person;
}
public Person getPerson(){
return this.person;
}
public void setPerson(Person person){
this.person = person;
}
public String getFullName(){
return this.getPerson() != null ? this.getPerson().getFirstName() + " " + this.getPerson().getLastName() : "";
}
public int compareTo(Member o) {
return this.getFullName().compareTo(o.getFullName());
}
@Override
public String toString() {
return "Member{" +
"person=" + person +
'}';
}
}
人class
class Person{
private String firstName;
private String lastName;
public String getFirstName(){
return this.firstName;
}
public String getLastName(){
return this.firstName;
}
public void setFirstName(String firstName){
this.firstName = firstName;
}
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
public Person(String firstname, String lastname){
this.firstName = firstname;
this.lastName= lastname;
}
}
一个解决方案是捕获抛出的空指针异常。像这样
private static List<Member> setMemberCacheOrderByFirstName(List<Member> members) {
Collections.sort(members, (m1, m2) -> {
try {
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}catch (NullPointerException e){
return 0;
}
});
return members;
}
或者手动检查是否存在不理想的空值。
private static List<Member> setMemberCacheOrderByFirstName(List<Member> members) {
Collections.sort(members, (m1, m2) -> {
// sort the list for firstnames
if (m1.getPerson() != null && m2.getPerson() != null && m1.getPerson().getFirstName() != null
&& m2.getPerson().getFirstName() != null) {
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
} else {
// Assuming any firstname is null
if (m1.getPerson().getFirstName() == null || m2.getPerson().getFirstName() == null
&& (m1.getPerson() != null && m2.getPerson() != null)) {
if (m1.getPerson().getFirstName() == null) {
m1.getPerson().setFirstName("");
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
m2.getPerson().setFirstName("");
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
// Assuming any member or person is null from schedulers
return "".compareTo("");
}
});
return members;
}
使用 Comparator.nullsFirst
或 Comparator.nullsLast
将是正确的选择。
如果您需要 first
处的空值。你可以使用这个
Collections.sort(members, (m1, m2) -> {
if(m1.getPerson() == null || m2.getPerson() == null ||
m1.getPerson().getFirstName() == null || m2.getPerson().getFirstName() == null){
return -1;
}
if(m1.getPerson() != null && m2.getPerson() != null &&
m1.getPerson().getFirstName() != null && m2.getPerson().getFirstName() != null){
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
return 0;
});
如果您需要 last
处的空值。你可以使用这个
Collections.sort(members, (m1, m2) -> {
if(m1.getPerson() == null && m2.getPerson() == null &&
m1.getPerson().getFirstName() == null && m2.getPerson().getFirstName() == null){
return -1;
}
if(m1.getPerson() != null && m2.getPerson() != null &&
m1.getPerson().getFirstName() != null && m2.getPerson().getFirstName() != null){
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
return 0;
});
优化的方法是。
Collections.sort(members, (m1, m2) -> {
if (m1.getPerson() == null || m2.getPerson() == null ||
m1.getPerson().getFirstName() == null ||
m2.getPerson().getFirstName() == null) {
return -1;
} else {
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
});
我有一个 Member
的列表,如果我有空值,需要在 java 8 collection.sort 方法中对 Person
firstName 进行空检查处理。目前我有 Member
实现 Comparable
接口以便 compareTo
另一个成员的全名。我从 TimSort binarySort 得到一个 NullPointerException。好像是 bug in OpenJDK. Found a solution to the NullPointerException in this question。上述问题的任何推荐解决方案以及我在下面提到的内容。
主程序
import java.util.Collections;
import java.util.List;
public class SortMembersByFirstName {
public static void main(String[] args) {
List<Member> members = getMembers();
List<Member> sorted = setMemberCacheOrderByFirstName(members);
for (Member mem: sorted) {
System.out.println(mem.toString());
}
}
private static List<Member> getMembers() {
Person tim = new Person("Tim", "Southee");
Member member1 = new Member(tim);
Person eoin = new Person("Eoin", "Morgan");
Member member2 = new Member(eoin);
Person moeenAli = new Person("Moeen", "Ali");
Member member3 = new Member(moeenAli);
Person timFirstNameNull = new Person(null, "Tim");
Member member4 = new Member(timFirstNameNull);
Person timFirstNameLastNameNull = new Person(null, null);
Member member5 = new Member(timFirstNameLastNameNull);
Person nullPerson = null;
Member member6 = new Member(nullPerson);
List<Member> members = new ArrayList<>();
members.add(member1);
members.add(member2);
members.add(member3);
members.add(member4);
members.add(member5);
members.add(member6);
return members;
}
/**
* Order list members by first name
*/
private static List<Member> setMemberCacheOrderByFirstName(List<Member> members) {
// TimSort.binarySort NPE
Collections.sort(members, (m1, m2) ->
m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName())
);
return members;
}
}
会员class
class Member implements Comparable<Member>{
private Person person;
public Member(Person person){
this.person = person;
}
public Person getPerson(){
return this.person;
}
public void setPerson(Person person){
this.person = person;
}
public String getFullName(){
return this.getPerson() != null ? this.getPerson().getFirstName() + " " + this.getPerson().getLastName() : "";
}
public int compareTo(Member o) {
return this.getFullName().compareTo(o.getFullName());
}
@Override
public String toString() {
return "Member{" +
"person=" + person +
'}';
}
}
人class
class Person{
private String firstName;
private String lastName;
public String getFirstName(){
return this.firstName;
}
public String getLastName(){
return this.firstName;
}
public void setFirstName(String firstName){
this.firstName = firstName;
}
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
public Person(String firstname, String lastname){
this.firstName = firstname;
this.lastName= lastname;
}
}
一个解决方案是捕获抛出的空指针异常。像这样
private static List<Member> setMemberCacheOrderByFirstName(List<Member> members) {
Collections.sort(members, (m1, m2) -> {
try {
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}catch (NullPointerException e){
return 0;
}
});
return members;
}
或者手动检查是否存在不理想的空值。
private static List<Member> setMemberCacheOrderByFirstName(List<Member> members) {
Collections.sort(members, (m1, m2) -> {
// sort the list for firstnames
if (m1.getPerson() != null && m2.getPerson() != null && m1.getPerson().getFirstName() != null
&& m2.getPerson().getFirstName() != null) {
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
} else {
// Assuming any firstname is null
if (m1.getPerson().getFirstName() == null || m2.getPerson().getFirstName() == null
&& (m1.getPerson() != null && m2.getPerson() != null)) {
if (m1.getPerson().getFirstName() == null) {
m1.getPerson().setFirstName("");
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
m2.getPerson().setFirstName("");
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
// Assuming any member or person is null from schedulers
return "".compareTo("");
}
});
return members;
}
使用 Comparator.nullsFirst
或 Comparator.nullsLast
将是正确的选择。
如果您需要 first
处的空值。你可以使用这个
Collections.sort(members, (m1, m2) -> {
if(m1.getPerson() == null || m2.getPerson() == null ||
m1.getPerson().getFirstName() == null || m2.getPerson().getFirstName() == null){
return -1;
}
if(m1.getPerson() != null && m2.getPerson() != null &&
m1.getPerson().getFirstName() != null && m2.getPerson().getFirstName() != null){
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
return 0;
});
如果您需要 last
处的空值。你可以使用这个
Collections.sort(members, (m1, m2) -> {
if(m1.getPerson() == null && m2.getPerson() == null &&
m1.getPerson().getFirstName() == null && m2.getPerson().getFirstName() == null){
return -1;
}
if(m1.getPerson() != null && m2.getPerson() != null &&
m1.getPerson().getFirstName() != null && m2.getPerson().getFirstName() != null){
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
return 0;
});
优化的方法是。
Collections.sort(members, (m1, m2) -> {
if (m1.getPerson() == null || m2.getPerson() == null ||
m1.getPerson().getFirstName() == null ||
m2.getPerson().getFirstName() == null) {
return -1;
} else {
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
});