Alex Kas
Alex Kas

Reputation: 13

NoSuchElementException on Stream iterating List<Object>

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

Answers (3)

Jeremiah Stones
Jeremiah Stones

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

Herbert Marshall
Herbert Marshall

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

Louis Wasserman
Louis Wasserman

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

Related Questions