Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling null in java streams with optional

What would be the best way of handling null if we have senario like below

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

studentsByCourseRoster.getUsers().stream().forEach(user -> {
    final UserDTOv2 userDTO = new UserDTOv2();
    userDTO.populateUserDataFromUserDTO(user, groupedUsers);
    users.add(userDTO);
});
like image 372
Seth De Avatar asked Dec 20 '18 07:12

Seth De


3 Answers

If you want to retain the single statement structure, you could use Optional.ofNullable and replace null with an empty list:

Optional.ofNullable(studentsByCourseRoster.getUsers())
        .orElse(Collections.emptyList())
        .forEach(user -> {
                     final UserDTOv2 userDTO = new UserDTOv2();
                     userDTO.populateUserDataFromUserDTO(user, groupedUsers);
                     users.add(userDTO);
         });
like image 117
Mureinik Avatar answered Sep 28 '22 04:09

Mureinik


With a slight modification to Mureinik's answer I would instead use :

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());

Using Stream.ofNullable in Java 9

List<UserDTOv2> users = Stream.ofNullable(studentsByCourseRoster.getUsers())
        .map(user -> {
            UserDTOv2 userDTO = new UserDTOv2();
            userDTO.populateUserDataFromUserDTO(user, groupedUsers);
            return userDTO;
        }).collect(Collectors.toList());
like image 38
Naman Avatar answered Sep 28 '22 05:09

Naman


What would be the best way of handling null if we have senario like below

The simplest solution to that under your current design is to do so with an if statement.

That is not saying it's the best way to "handle" this problem but rather the best way to handle this is never to allow the list to be in a null state in the first place as also mentioned in the comments.

Have an empty list as the default value, this will save you quite a huge amount of if checks around your codebase depending on how many times getUsers() is being used and most importantly you wouldn't have to worry about NullPointerExeception's because they should never occur.

On another note, whenever you seem to see your self calling stream() on some collection and then immediately calling forEach you should realise it's wrong; 1) in the sense that you could easily call forEach directly on the list i.e. studentsByCourseRoster.getUsers().forEach(...) 2) streams and side-effect just don't work together well.

like image 34
Ousmane D. Avatar answered Sep 28 '22 05:09

Ousmane D.