簡體   English   中英

使用可選項在Java流中處理null

[英]Handling null in java streams with optional

如果我們有如下所示的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語句。

這並不是說它是“處理”這個問題的最好方法,而是處理這個問題的最好方法是永遠不要讓列表首先處於空狀態,如評論中所提到的那樣。

有一個空列表作為默認值, if你的代碼庫周圍檢查取決於使用getUsers()次數,這將為你節省相當多的錢,最重要的是你不必擔心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的答案之外,還有一種方法可以選擇這個。 無需創建空列表,我們只能通過以下方式傳遞執行非null的情況:

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

Nullable可選也適用於嵌套的空引用,例如我們有一些結構:

class User {
    @Getter
    Address address;
}

class Address {
    @Getter
    String street;
}

然后而不是寫作

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

我們可以使用Optional:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM