【问题标题】:Sorting a nested object with two values using Java 8 Comparator使用 Java 8 Comparator 对具有两个值的嵌套对象进行排序
【发布时间】:2019-11-19 09:40:37
【问题描述】:

我正在尝试对学生列表进行排序,其中student 具有地址和语言类的实例变量

Class Student {
 Address address;
 Language language;
 //Other fields
  //Setter getters
}

Class Address {

 String streetName;
 //Other fields
 //Setter getters
}

Class Language {
 String name;
 //Other fields
 //Setter getters

}

我正在尝试先按街道名称然后按语言对这个学生列表进行排序,并希望使用以下代码将空值保留在底部,但是当地址或语言为空时得到NullPointerException

list.sort(Comparator.nullsLast(Comparator.comparing((Student student-> student.getAddress().getStreetName()).thenComparing((Student student) -> student.getLanguage().getName())));

【问题讨论】:

  • 如果地址为空,student.getAddress().getStreetName() 会抛出 NPE
  • 您的比较器处理Studentnull 的情况,而不是属性值为null 的情况。与this answer比较
  • 谢谢@Holger。你能建议如何处理空地址和空语言。仍然得到NullPointerException。

标签: java sorting java-8 comparator


【解决方案1】:

最好的方法是检查空值。因此,您可以轻松处理未来的情况。 也可以参考这个1。 Comparator 接口的方法不支持空值,所以一定要检查https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

【讨论】:

    【解决方案2】:

    首先,您需要更改 Address 和 Language 类以实现 Comparable 并将 compareTo 函数的逻辑按 streetName(如果是 Address)和按名称(如果是 Language)进行比较。

        class Language implements Comparable<Language>{
        String name;
    
    
            public String getName(){
            return name;
        }
    
            @Override
            public int compareTo(Language o) {
                return this.name.compareTo(o.name);
            }
            //Other fields
        //Setter getters
    
        }
    
        class Address implements Comparable<Address> {
    
        String streetName;
    
            @Override
            public int compareTo(Address o) {
                return this.streetName.compareTo(o.streetName);
            }
    
    
            //Other fields
        //Setter getters
        }
    

    然后将调用改为如下排序:

        students.sort(Comparator.comparing((Student student)-> student.address, 
        Comparator.nullsLast(Address::compareTo))
                        .thenComparing((Student student) -> student.language, 
        Comparator.nullsLast(Language::compareTo)));
    

    这样,您将地址的比较委托给地址类,并将语言的比较委托给语言类。您可以通过在 Address 和 Language 类中使用函数 compareTo 调用 compare.nullsLast 来强制空值位于最后。

    ----更新----- 根据 Holge 的评论,您可以用以下代码替换最后的代码:

          students.sort(Comparator.comparing((Student student)-> 
          student.address, Comparator.nullsLast(Comparator.naturalOrder()))
                .thenComparing((Student student) -> student.language, 
          Comparator.nullsLast(Comparator.naturalOrder())));
    

    【讨论】:

    • 当一个类实现Comparable时,你不需要像Type::compareTo那样创建一个新的比较器。您可以使用现有的Comparator.naturalOrder()
    • @Holger 谢谢你的信息,第一次知道这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 2023-03-21
    • 2019-06-25
    • 1970-01-01
    • 2017-02-05
    • 2021-11-16
    • 2017-07-01
    相关资源
    最近更新 更多