Reputation: 13
hi! Try to use this stream, but i got NoSuchElementException on
var scores = findAllByBarcode
.stream()
.iterator()
.next()
.getMpProductFeedbacks()
.stream()
.filter(mpProductFeedback -> mpProductFeedback.getId()==mpProductFeedbackId)
.iterator()
.next()
.getMpPersonScores()
.stream()
.map(mpPersonScore -> {
var score = new ScoreType();
score.setUserScore(mpPersonScore.getMpPersonScore());
score.setUser(mpPersonScore.getMpPersonLogin());
score.setUserComment(mpPersonScore.getMpPersonComment());
return score;
})
.toList();
got exception after part
filter(mpProductFeedback -> mpProductFeedback.getId()==mpProductFeedbackId)
.iterator()
.next()
tried to use orElse, but it works only with .equals i already have == between two longs.
Upvotes: 1
Views: 98
Reputation: 1
To piggyback on Louis' answer, you can complement .findFirst() with Optional.ofNullable(...).orElse(...) if you'd like to keep this code as a single statement like you have. This allows you to have the null safety of Optionals throughout withing having to actually check at each stage to see if the Object or list is actually there. I created a test method as an example for you; however please forgive the class names. They weren't mentioned in the question itself, so I made a few of them up, but this should give the basic idea:
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.Test;
class FilterAndMapTest {
@Test
void filterAndMapToScoreTypesTest() {
List<ProductDetails> findAllByBarcode = new ArrayList<>();
ProductDetails productDetail = new ProductDetails();
List<ProductFeedback> mpProductFeedbacks = new ArrayList<>();
ProductFeedback productFeedback = new ProductFeedback();
productFeedback.setId(1L);
List<MpPersonScore> personScores = new ArrayList<>();
MpPersonScore personScore = new MpPersonScore();
personScore.setMpPersonScore(123L);
personScore.setMpPersonLogin("test login");
personScore.setMpPersonComment("test comment");
personScores.add(personScore);
productFeedback.setMpPersonScores(personScores);
mpProductFeedbacks.add(productFeedback);
productDetail.setMpProductFeedbacks(mpProductFeedbacks);
findAllByBarcode.add(productDetail);
Long mpProductFeedbackId = 1L;
var scores = Optional
.ofNullable(Optional
.ofNullable(findAllByBarcode.stream().findFirst().orElse(new ProductDetails())
.getMpProductFeedbacks())
.orElse(new ArrayList<>()).stream()
.filter(mpProductFeedback -> mpProductFeedback.getId() == mpProductFeedbackId).findFirst()
.orElse(new ProductFeedback()).getMpPersonScores())
.orElse(new ArrayList<>()).stream().map(mpPersonScore -> {
var score = new ScoreType();
score.setUserScore(mpPersonScore.getMpPersonScore());
score.setUser(mpPersonScore.getMpPersonLogin());
score.setUserComment(mpPersonScore.getMpPersonComment());
return score;
}).toList();
assertEquals(1, scores.size());
assertEquals(123L, scores.get(0).getUserScore());
assertEquals("test login", scores.get(0).getUser());
assertEquals("test comment", scores.get(0).getUserComment());
}
}
Upvotes: 0
Reputation: 166
Assuming we're dealing with nested Collections
List<ScoreType> scores = findAllByBarcode
.stream()
.map( b -> b.getMpProductFeedbacks() )
.flatMap( Collection::stream )
.filter( feedback -> feedback.getId() == mpProductFeedbackId )
.map( feedback -> feedBack.getMpPersonScores() )
.flatMap( Collection::stream )
.map( personScore -> {
ScoreType score = new ScoreType();
score.setUserScore( personScore.getMpPersonScore() );
score.setUser( personScore.getMpPersonLogin() );
score.setUserComment( personScore.getMpPersonComment() );
return score;
})
.toList();
Upvotes: 0
Reputation: 198471
Well, it sounds like there is no element that satisfies the condition. Consider using findFirst()
instead of .iterator().next()
to properly handle the Optional
.
Upvotes: 2