Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing and filtering Java class list elements by id

Tags:

java

I have a result of type User as follows:

List<User> result  = (getting values from db)

the properties of class User that I need are:

private Integer id,
private String name, 
private List<Books> books = new ArrayList<>(); 

etc.

And Class Books has a field Id to.

Given that I have the user Id, and the books Id. I would like to access the other results inside the array book, for that book id.

So I need to -> give the result variable a specific userId, and access books property for that user, then give a bookId, and access book properties for that book id, in that user. I tried using java streams:

List<BooksDetails> userBook = result.stream()
  .filter(user -> user.getId() == 1)
  .collect(Collectors.toList())
  .get(0)
  .getBooks()
  .stream()
  .filter(book -> book.getId() == 2)
  .collect(Collectors.toList())
  .get(0)
  .getBooksDetails();

But sometimes I get index out of bound error when accessing get(0) element. And it seems there might be a cleaner solution to this. What approaches can I use to accessing nested properties by giving the associated id's in a list? OR would I have to convert it to a nested map instead?

like image 968
NoahH Avatar asked Mar 28 '26 20:03

NoahH


2 Answers

It sounds like you want to do the following:

  • filter users for userId == 1
  • then flatMap the Books list
  • filter those books for bookid == 2
  • and then get the book details and store in a list
record BooksDetails(){};
record Books(int getId, List<BooksDetails> getBooksDetails){}
record User(int getId, List<Books> getBooks){}
  
List<User> result = new ArrayList<>();
         
Optional<List<BooksDetails>> bd = result.stream()
     .filter(user -> user.getId() == 1)
     .flatMap(b->b.getBooks().stream())
     .filter(book -> book.getId() == 2)
     .findFirst()
     .map(Books::getBooksDetails);

Update

I have updated my answer to include records which shows my understanding of your classes. Since the ultimate result is based on a book Id, I am presuming that 1) it is unique. and 2) there are no duplicate books in the list. So this will return an Optional<List<BooksDetails>> which contains the list of book details for that bookId for the userId. If not book is found, it returns an empty optional.

Also,I replaced the flatMap with a Lambda and it worked.

like image 174
WJS Avatar answered Mar 31 '26 07:03

WJS


List result = (getting values from db)

Might be not the answer you expect, but this predicate-filter (for user.id == 1 and book.id == 2) & find-first probably could be implemented in a layer before the result, as (database/SQL) query.

For example:

SELECT u.*
FROM users u 
JOIN books b ON b.user_id = u.id
WHERE u.id = 1 AND b.id = 2 
like image 39
hc_dev Avatar answered Mar 31 '26 08:03

hc_dev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!