NoSuchElementException on Stream iterating List<Object>

57 views Asked by At

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.

3

There are 3 answers

2
Herbert Marshall On BEST ANSWER

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();
0
Louis Wasserman On

Well, it sounds like there is no element that satisfies the condition. Consider using findFirst() instead of .iterator().next() to properly handle the Optional.

0
Jeremiah Stones On

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());
    }

}