简体   繁体   中英

Filter a Bean from List of List of Beans with exceptions handled in Java 8

I have a two Bean Classes: User and Post.

User have the following members:

private Integer id;
private String name;
private Date birthDate;
private List<Post> userPosts;

Post have the following members:

private Integer id;
private String title;
private Date postDate;

I want to extract one post for a corresponding user. The methods will have the userId and postId as input. How can I convert the following logic in Java 8?

public Post findOnePost(int userId, int postId) {
    boolean isUserFound = false;
    for (User user : users) {
        if (user.getId() == userId) {
            isUserFound = true;
            for (Post post : user.getUserPosts()) {
                if (post.getId() == postId) {
                    return post;
                }
            }
        }
    }
    if (!isUserFound) {
        throw new UserNotFoundException("userId- " + userId);
    }
    return null;
}

If you want to throw UserNotFoundException, when user does not exist, but return null, when user is not containing desired post:

List<User> foundUsers = users.stream()
.filter(user -> Objects.equals(user.getId(), userId));
.collect(toList());
if(foundUsers.isEmpty()){
 throw new UserNotFoundException("userId- " + userId);
}
return foundUsers.stream().map(User::getUserPosts)
.flatMap(List::stream)
.filter(post-> Objects.equals(user.getId(), userId))
.findFirst().orElse(null);

Otherwise it can be simplified to single stream:

public Optional<Post> findOnePost(int userId, int postId) {
    return users.stream()
      .filter(user -> Objects.equals(user.getId(), userId)) // find user
      .flatMap(user-> user.getUserPosts().stream()) // extract posts
      .filter(post-> Objects.equals(post.getId(), postId)) //filter posts
      .findFirst(); // find first matching
 }

Return Optional instead of null or an Exception. Class using this method will decide, to throw an exception or not. Secondly it's harmful to return null value, this may cause problems.

Using Objects.equals(a,b) will check for null values, preventing NPE

Even though earlier answer is accepted, I'll provide mine as you added have asked for condition if (;isUserFound) {throw new UserNotFoundException("userId- " + userId);} . I think, variable isUserFound and exception UserNotFoundException is misleading because what you want is to throw exception when no matching user and post is found.

public Post findOnePost(int userId, int postId) throws UserNotFoundException {
    return users.stream()
        .filter(user -> Objects.equals(user.getId(), userId))
        .flatMap(user -> user.getUserPosts().stream())
        .filter(post -> Objects.equals(post.getId(), postId))
        .findFirst()
        .orElseThrow(() -> new UserNotFoundException("userId- " + userId));
  }

I'm assuming UserNotFoundException is checked exception, if not remove from method declaration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM