2

I am working with classes with multi level depth. I am trying to filter in the inner depth but i am receiving the error

Bad return type in lambda expression: Stream<InnerClassName> cannot be converted to boolean 

The structure of my Classes is

class A {
    List<B> B;
    Integer Id;
}

class B {
        List<C> C;
        Integer Id;
    }


class C {                    
         Integer Id;
        }

If I have List called AList I have tried doing

AList.getBlist().stream().filter(bList -> bList.getId.equals(5));

Which works fine. What i am trying to accomplish is filter with values inside Class C which could be obtained by Blist.getClist

2
  • What is your final output supposed to be? List<A> or List<C>? Commented Feb 19, 2019 at 13:54
  • 1
    List<A> would be fine i wanted to check if linked objects with condition exist, if only List<C> is possible it would not be a problem. Commented Feb 19, 2019 at 13:56

1 Answer 1

3

If you're trying to filter the content of List<A> and obtain the same format as output, you can perform it as :

List<A> output = aList.stream()
        .filter(a -> a.getBList().stream() // bList from a
                .flatMap(b -> b.getCList().stream()) // cList from each b
                .anyMatch(c -> c.getId() == 5)) // equals(5)
        .collect(Collectors.toList());

The above code filters in all those 'A' from the List<A> such that any 'C' part of a List<C> within any 'B' part of a List<B> within A matches the given condition.

Sign up to request clarification or add additional context in comments.

5 Comments

c.getId().equals(5) can only be true when c.getId() returns an Integer. In that case, it’s preferable to use c.getId() == 5 which will evaluate to the same result, but would raise a compiler error if c.getId() does not return a compatible numeric type (whereas Object.equals(Object) accepts anything, even when impossible to ever be true).
@Holger Point noted. Thanks. Does this post which is 8yrs old, need a revisit though?
Unfortunately, this is still valid. When both sides of == or != are objects, a reference comparison will be made. The best solution is to ensure that at least one side is not an object. E.g. if the task is not about matching with the constant 5, but a parameter Integer matchValue, unbox it before the Stream operation, like int valueToUse = matchValue;, followed by anyMatch(c -> c.getId() == valueToUse) within the Stream operation.
@Holger Why not instead compare objects with equals in the latter case? Just because there is no concrete type bound there?
That’s one reason. Further, the type promotion behavior differs, e.g. how int and long are compared, or how null (on the right hand side) is handled.

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.