2

I have some code that looks like this.

class A {}
class B extends A {
    private String name; // assume there's a getter
}
class C extends A {
    private List<B> items = new ArrayList<>(); // assume a getter
}

In another class, I have an ArrayList (ArrayList<A>). I'm trying to map this list to get all the names.

List<A> list = new ArrayList<>();
// a while later
list.stream()
    .map(a -> {
        if (a instanceof B) {
            return ((B) a).getName();
        } else {
            C c = (C) a;
            return c.getItems().stream()
                .map(o::getName);
        }
    })
    ...

The problem here is that I end up with something like this (JSON for visual purposes).

["name", "someName", ["other name", "you get the idea"], "another name"]

How can I map this list so I end up with the following as my result?

["name", "someName", "other name", "you get the idea", "another name"]
2
  • Use a flatMap.. It would be useful if you show how you collect the result after the map step (the else returns a Stream whereas the if part returns a String). Are you collecting it into a List<Object>? Commented Jan 23, 2019 at 8:27
  • take a look at stackoverflow.com/questions/26684562/… it will help you understand the use of flatMap Commented Jan 23, 2019 at 8:38

1 Answer 1

4

Use flatMap:

list.stream()
    .flatMap(a -> {
        if (a instanceof B) {
            return Stream.of(((B) a).getName());
        } else {
            C c = (C) a;
            return c.getItems().stream().map(o::getName);
        }
    })
    ...

This will produce a Stream<String> of all the names, without nesting.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.