Java 8 - 可选<CustomizedObject> 获取 CustomizedObject 中列表的第一个元素

Java 8 - Optional<CustomizedObject> get first element of the list within CustomizedObject

我不知道该怎么做

class Department {
    String deptName;
    List<Person> employees;
}

class Person {
    String personName;
}

问题陈述是获取在特定部门工作的人员的名字。 这个部门可以是可选的。这就是我的方法的样子 -

String getFirstPerson(Optional<Department> department, String defaultName) {
// TODO: 
}

我知道这样做的传统方法,但希望看到一些 Java 8 + lambda 方法来简化它。 在这里还是个新手 - 如果我使用的格式不正确,请原谅。

我还有一个默认名称,以防找不到该值。

P.S。我知道将 Optional 作为方法参数发送不是最佳做法。这不是实际的代码。我只是想简化它。

您可以在 Optional 上使用 map 函数获取员工列表,然后使用 stream 获取名字或 return defaultName。即使 Optional 为空,您也会得到 defaultName

String getFirstPerson(Optional<Department> department, String defaultName) {

   return department.map(d->d.getEmployees().stream().map(Person::getPersonName).findFirst().orElse(defaultName)).orElse(defaultName));
}

如果您有机会在 getEmployees 上获得 null,您可以使用以下方法

department.map(Department::getEmployees)
          .filter(Objects::nonNull)
          .map(emp->emp.stream().map(Person::getPersonName).findFirst().orElse(defaultName)).orElse(defaultName)

一种简化的方法是使用 emptyList 表示缺席部门或可为 nullable employees:

String getFirstPerson(Optional<Department> department, String defaultName) {
    return department.map(Department::getEmployees)
            .orElse(Collections.emptyList()) // get rid of this ensuring non null List
            .stream()
            .map(Person::getPersonName)
            .findFirst()
            .orElse(defaultName);
}

实际在:

department.map(Department::getEmployees)
          .filter(Objects::nonNull)
          .map(emp->emp.stream().map(Person::getPersonName).findFirst().orElse(defaultName)).orElse(defaultName)

我们不必检查非空,因为如果员工为空,.map(Department::getEmployees) 将 return Optional.empty()。参见 Optional documentation。 正确答案是没有冗余过滤器:

department.map(Department::getEmployees)
          .map(emp->emp.stream().map(Person::getPersonName).findFirst().orElse(defaultName)).orElse(defaultName)

或者:

department.map(Department::getEmployees)
          .map(List::stream)
          .map(Stream::findFirst)
          .flatMap(Functions.identity())
          .map(Person::getPersonName)
          .orElse(defaultName);