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?
It sounds like you want to do the following:
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With