使用可选处理Java流中的null

时间:2018-12-20 07:09:05

标签: java java-8 null optional

如果我们有如下所示的senario,那么处理空值的最佳方法是什么

//mocking for demonstraton  
studentsByCourseRoster.setUsers(null);

studentsByCourseRoster.getUsers().stream().forEach(user -> {
    final UserDTOv2 userDTO = new UserDTOv2();
    userDTO.populateUserDataFromUserDTO(user, groupedUsers);
    users.add(userDTO);
});

5 个答案:

答案 0 :(得分:6)

如果要保留单个语句结构,可以使用Optional.ofNullable并将null替换为空列表:

Optional.ofNullable(studentsByCourseRoster.getUsers())
        .orElse(Collections.emptyList())
        .forEach(user -> {
                     final UserDTOv2 userDTO = new UserDTOv2();
                     userDTO.populateUserDataFromUserDTO(user, groupedUsers);
                     users.add(userDTO);
         });

答案 1 :(得分:3)

对Mureinik的回答稍作修改后,我会改用:

List<UserDTOv2> users = Optional.ofNullable(studentsByCourseRoster.getUsers())
        .orElse(Collections.emptyList())
        .stream()
        .map(user -> {
            UserDTOv2 userDTO = new UserDTOv2();
            userDTO.populateUserDataFromUserDTO(user, groupedUsers);
            return userDTO;
        }).collect(Collectors.toList());

在Java 9中使用Stream.ofNullable

List<UserDTOv2> users = Stream.ofNullable(studentsByCourseRoster.getUsers())
        .map(user -> {
            UserDTOv2 userDTO = new UserDTOv2();
            userDTO.populateUserDataFromUserDTO(user, groupedUsers);
            return userDTO;
        }).collect(Collectors.toList());

答案 2 :(得分:1)

  

如果我们有类似senario的话,处理null的最佳方法是什么   下面

当前设计下最简单的解决方案是使用if语句。

这并不是说这是“处理”此问题的最佳方法,而是处理的最佳方法,这绝不是让列表首先处于空状态,这也是在评论中提到。

将一个空列表作为默认值,这将为您节省大量if检查代码,具体取决于使用getUsers()的次数,最重要的是您不会必须担心NullPointerExeception,因为它们永远都不会发生。

另一方面,每当您看到自己在某个集合上调用stream()然后立即调用forEach时,您应该意识到这是错误的; 1)从某种意义上讲,您可以轻松地直接在列表上调用forEach,即studentsByCourseRoster.getUsers().forEach(...) 2)流和副作用不能很好地协同工作。

答案 3 :(得分:0)

您还可以通过filter(Objects :: nonNull)过滤空对象:

studentsByCourseRoster.getUsers().stream().filter(Objects::nonNull).forEach(user -> {
    final UserDTOv2 userDTO = new UserDTOv2();
    userDTO.populateUserDataFromUserDTO(user, groupedUsers);
    users.add(userDTO);
});

答案 4 :(得分:0)

除了纠正@Murenik的答案外,还有另一种方法用可选的方式编写。无需创建空列表,我们只能通过以下方式传递执行非null的情况:

    Optional.ofNullable(nullableUsers)
            .ifPresent(users -> users.forEach(user -> {
                // work with user
            }));

nullable可选也适用于嵌套的null引用,例如我们有一些结构:

class User {
    @Getter
    Address address;
}

class Address {
    @Getter
    String street;
}

然后代替

if (user.getAddress() != null && user.getAddress().getStreet() != null) {
   // work with street
}

我们可以使用可选:

    Optional.ofNullable(user)
            .map(User::getAddress)
            .map(Address::getStreet)
            .ifPresent(street -> {
                // work with street
            });