【问题标题】:Null check in Stream filter流过滤器中的空检查
【发布时间】:2020-09-23 13:35:00
【问题描述】:

我有一个学生对象列表studentList,如下所示。

Student1 = new Student("Student1", 10);
Student2 = new Student("Student2", 11);


Student {
 String name;
 int age;
}

我想对列表进行过滤并获取特定学生的年龄。 我使用 java 8 流尝试了与下面相同的操作。

int age = studentList.stream()
        .filter(x -> x.getName.equals("Student1"))
        .findFirst()
        .get()
        .getAge();

但是当我传递一个不在列表中的学生姓名时,比如 Student5,它会抛出一个空指针异常。为此,我给出了如下的空检查

Student s = studentList.stream()
        .filter(x -> x.getName.equals("Student1"))
        .findFirst()
        .get();

if(s != null){
  age = s.getAge();
}

除了像这样拆分这个空检查,是否可以在 stream().filter() 代码本身中容纳空检查?

【问题讨论】:

  • get() 在一个空的可选项上会抛出一个NoSuchElementException,而不是NullPointerException
  • 当没有学生匹配时,这不是你想要的完整情况吗?

标签: java-8 java-stream


【解决方案1】:

Stream#findFirst 返回 Optional<T> 如果存在,您可以重新映射哪个值:

int age = studentList.stream()
    .filter(x -> "Student1".equals(x.getName()))
    .findFirst()
    .map(Student::getAge)
    .orElse(0);

【讨论】:

  • 您可以使用int age = studentList.stream() .filter(x -> "Student1".equals(x.getName())) .mapToInt(Student::getAge) .findFirst() .orElse(0);避免装箱开销
【解决方案2】:

首先,反转您的测试,以防getName 返回空值。 equals 方法应该在进行比较之前检查 null。然后添加一个条件以防学生不匹配。

int age = studentList.stream()
           .filter(x -> "Student1".equals(x.getName()))
           .mapToInt(Student::getAge).findFirst().orElse(0);

根据Holger 的出色建议修改了我的答案,以减少boxing 开销。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-05
    • 2011-04-25
    • 1970-01-01
    • 2020-09-07
    • 2011-09-17
    • 2011-11-17
    • 1970-01-01
    • 2017-01-31
    相关资源
    最近更新 更多