Java 优化if-else语句,因为使用lambda进行空检查?

Java 优化if-else语句,因为使用lambda进行空检查?,java,Java,我有下面的例子,感觉可读性不好。 我必须做很多检查,因为getStudents()可以为null,getTests()也可以为null。我必须先做IStudentsavailable(),然后再做ISestavailable() 如何将此示例转换为不需要这些检查的lambda表达式? 我很乐意得到一些提示。谢谢 if(school.isStudentsAvailable()){ sendMailtoStudents(school.getStudents());

我有下面的例子,感觉可读性不好。 我必须做很多检查,因为getStudents()可以为null,getTests()也可以为null。我必须先做IStudentsavailable(),然后再做ISestavailable()

如何将此示例转换为不需要这些检查的lambda表达式? 我很乐意得到一些提示。谢谢

      if(school.isStudentsAvailable()){
        sendMailtoStudents(school.getStudents());
        
        if(school.getStudents().isTestAvailable()) {
        printTests(school.getStudents().getTests());
         }
      }
我必须做很多检查,因为getStudents()可以为null,getTests()也可以为null

啊,你有一股代码的味道

有许多方法可以处理NUI的概念(未初始化、未知、不相关)
null
是一种方式,Optional等包装类型是另一种方式,annotation是第三种方式,sentinel值是第四种方式

但听起来这不是NUI!听起来像是
getStudents()
返回null作为一种表达方式:学生为零

换句话说,它传递的是空的,而不是NUI

用null表示empty是错误的,因为与NUI不同,empty的语义符合您类型的约定
school.getStudents
返回一个列表(或集合、集合、映射或数组-表示集合的某种类型),所有这些类型都可以很好地表示空类型

换句话说,修复方法是转到
getStudents
方法的代码并替换
返回null带有
返回列表of()

那么您的调用代码就简单多了。而不是:

List<Student> students = getStudents();
if (students != null) {
    for (Student student : students) {
        // code here
    }
}
毫无疑问,眼球会立刻喜欢上它。它更容易阅读

但是,假设您不能更改getStudents,因为它是提供的

然后,当面对设计糟糕到近乎崩溃的API时,您应该做的是:编写一个包装器:

public static List<Student> fixedGetStudents(School school) {
    List<Student> students = school.getStudents();
    return students == null ? List.of() : students;
}
公共静态列表fixedGetStudents(学校){
List students=school.getStudents();
return students==null?List.of():学生;
}

就这么说吧。每次使用时尝试“修复它”意味着每次使用getStudents时都在编写代码来解决潜在的空值问题,这是一个样式错误,因为它违反了DRY(不要重复您自己)。

可能为空,您的意思是他们可以返回空值?与lambda无关的一件事是让getStudents()等方法返回一个空集合而不是null,这将删除一些检查,并且根据sendMailtoStudents&printTests的工作方式,您可能不需要在引用if语句时更改它们,如果这种方式完全正确。不要试图修复没有损坏的东西。
public static List<Student> fixedGetStudents(School school) {
    List<Student> students = school.getStudents();
    return students == null ? List.of() : students;
}