Convert list to optional of map

Viewed 315

I have a list of User where I want to convert it into a Map of Id and User. However, the list can be null, so if I use Stream to convert it will throw exception.

public Map<Long, User> getUserMap() {
  List<User> users = getUserList(); //the method getUserList() can
  // return null and this method can not be further changed

  return users.stream()
              .collect(Collectors.toMap(User::getId, user - > user)));
  //throwing nullPointerException when users is null
}

Instead of returning an empty Map, I consider to change the return type as Optional. In the following, it seems to me that if I already use Optional maybe the whole operation can be chained up into one-liner similar to the Stream operation, rather doing the if else null checking. Is this possible ?

public Optional<Map<Long, User>> getUserMap() {
  List<User> users = getUserList(); //the method getUserList() can return null
  
  if (users == null) {
    return Optional.empty();
  } else {
    return Optional.of(users.stream()
                   .collect(Collectors.toMap(User::getId, user - > user)));
  }
}


//not working
public Optional<Map<Long, User>> getUserMap() {
      List<User> users = getUserList(); //the method getUserList() can return null

 return Optional.ofNullable(users)
         .stream()
         .collect(Collectors.toMap(User::getId, user -> user));
}
1 Answers

You said:

I have a list of User where I want to convert it into a Map of Id and User. However, the list can be null, so if I use Stream to convert it will throw exception

So rather that go down the Optional route, let’s address your original problem with a called method that returns either a populated List or a null rather than an empty list. Your can easily replace any received null with an empty list. If you do that, your original approach will yield an empty map as you desired.

Change this:

List<User> users = getUserList(); 

… to this:

List<User> users = Objects.requireNonNullElse( getUserList() , List.of() ) ;  // Now `users` is never null. 

This eliminates the possibility of a null reaching, and breaking, your stream-based code.

Related