如果我们在下面有这样的senario,处理null的最佳方式是什么
//mocking for demonstraton
studentsByCourseRoster.setUsers(null);
studentsByCourseRoster.getUsers().stream().forEach(user -> {
final UserDTOv2 userDTO = new UserDTOv2();
userDTO.populateUserDataFromUserDTO(user, groupedUsers);
users.add(userDTO);
});
如果您想保留单个语句结构,可以使用Optional.ofNullable
并用空列表替换null
:
Optional.ofNullable(studentsByCourseRoster.getUsers())
.orElse(Collections.emptyList())
.forEach(user -> {
final UserDTOv2 userDTO = new UserDTOv2();
userDTO.populateUserDataFromUserDTO(user, groupedUsers);
users.add(userDTO);
});
对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());
如果我们有类似senario的函数,处理null的最佳方式是什么低于
在当前设计中,最简单的解决方案是使用if
语句。
这并不是说这是"处理"这个问题的最佳方式,而是处理的最佳方式——正如评论中所提到的,永远不要让列表处于空状态。
默认值为空列表,这将根据getUsers()
的使用次数,为您的代码库节省大量的if
检查,最重要的是,您不必担心NullPointerExeception
的检查,因为它们永远不会发生。
另一方面,每当你看到自己在某个集合上调用stream()
,然后立即调用forEach
时,你应该意识到这是错误的;1( 从某种意义上说,你可以很容易地直接在列表上调用forEach
,即studentsByCourseRoster.getUsers().forEach(...)
2(流和副作用不能很好地协同工作。
您也可以通过filter(objects::nonNull(:过滤空对象
studentsByCourseRoster.getUsers().stream().filter(Objects::nonNull).forEach(user -> {
final UserDTOv2 userDTO = new UserDTOv2();
userDTO.populateUserDataFromUserDTO(user, groupedUsers);
users.add(userDTO);
});
除了更正@Murenik的答案外,还有一种用可选的方法来写这篇文章。无需创建空列表,我们可以通过以下方式传递执行非空情况:
Optional.ofNullable(nullableUsers)
.ifPresent(users -> users.forEach(user -> {
// work with user
}));
Nullable optional也适用于嵌套的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
});