0

I am using java8 streams to iterate two lists, In that one list contains some custom objects and another contains string.

With this, I have to call a method by passing custom object and sting as a input and then I have to get the count.

This is what I tried:

public int returnCode()  {
        /*int count = 0;
         * list.forEach(x -> {
            list2.forEach(p -> {
                count+ = myDao.begin(conn, x.getCode(), p);
            });
            return count;
        });*/   
    }

compiler is giving an error that count should be final.

Can anyone, give me how to do this in a better way.

3
  • Trivially, have you tried just declaring final int count = 0 instead of what you currently have? Commented Jun 15, 2018 at 2:51
  • What is the content of list1 and list2 intern? Which one holds objects and which one holds String ? Commented Jun 15, 2018 at 2:51
  • @Tim, I tried already, but the compiler is giving quick fiix that, remove final modifer again Commented Jun 15, 2018 at 3:03

2 Answers 2

1

What you're attempting to do is not possible as local variables accessed from a lambda must be final or effectively final i.e. any variable whose value does not change.

You're attempting to change the value of count in the lambda passed to the forEach hence the compilation error.

To replicate your exact code using the stream API, it would be:

int count = list.stream()
                .limit(1)
                .flatMapToInt(x -> list2.stream().mapToInt(p -> myDao.begin(conn, x.getCode(), p)))
                .sum();

However, if you want to iterate over the entire sequence in list and not just the first then you can proceed with the following:

int count = list.stream()
                .flatMapToInt(x -> list2.stream().mapToInt(p -> myDao.begin(conn, x.getCode(), p)))
                .sum();
Sign up to request clarification or add additional context in comments.

5 Comments

tried your code, giving invalid output 12 instead of 2; question updated.
@Creator don't vandalise the post by changing the context completely. if you've got a new problem then you need to put up a new question.
@Creator I've reverted the post to how it was initially. the first example snippet in my answer is the exact equivalent of the code in your post but using the stream API.
@Creator I didn't say to update your post. instead, I said to post a new question regarding your new problem . your initial problem has already been solved. post reverted again..
Please find the question here: stackoverflow.com/questions/50888506/…
1

Lambdas mainly substitutes anonymous inner classes. Inside an anonymous inner class you can access only final local variables. Hence the same holds true with lambda expressions. Local variable is copied when JVM creates a lambda instance, hence it is counter intuitive to allow any update to them. So declaring the variable as final would solve the issue. But if you make it final you won't be able to do this, leading to another pitfall.

count+ = myDao.begin(conn, x.getCode(), p);

So your solution is not good and does not comply with lambda. So this will be a one way of doing it.

final int count = customObjects.stream()
    .mapToInt(co -> strings.stream().mapToInt(s -> myDao.begin(conn, co.getCode(), s)).sum())
    .sum();

1 Comment

tried your snippet; it is giving incorrect value as 12. I deally it should give 2 as output. question is updated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.