2

I am not so familiar with Java 8 (still learning) and looking to see if I could find something equivalent of the below code using flatMap.

I use lombok @Builder (you can ignore that part)

Few checks that we might need - Lists could be empty

A rough sketch of my objects - class Scratch {

public static void main(String[] args) {
    List<Object2> object2List = new ArrayList<>();
    object2List.add(Object2.builder().needThisList(Arrays.asList("good" , "bad")).build());
    object2List.add(Object2.builder().needThisList(Arrays.asList("worse" , "awesome")).build());

    List<Object2> object2List_2 = new ArrayList<>();
    object2List_2.add(Object2.builder().needThisList(Arrays.asList("good1" , "bad1")).build());
    object2List_2.add(Object2.builder().needThisList(Arrays.asList("worse1" , "awesome1")).build());

    List<Object1> object1List = new ArrayList<>();
    object1List.add(Object1.builder().object2List(object2List).build());
    object1List.add(Object1.builder().object2List(object2List_2).build());

    //Please get me final list of all the Strings


   }
}

@Builder
class Object1 {
    List<Object2> object2List;
}

@Builder
class Object2 {
    List<String> needThisList;
}
meso
  • 493
  • 2
  • 5
  • 15
  • The answer is in the question. Use flatMap. Have you tried using it? What is the concrete problem you faced? – JB Nizet Jul 23 '19 at 20:35
  • Well I am getting confused on the correct use of it :( List finalList = object1List.stream() .flatMap() .map() .collect(Collectors.toList()); – meso Jul 23 '19 at 20:37
  • I am getting a bit confused with the correct use of it. I would have to again do a stream inside the map function? – meso Jul 23 '19 at 20:39
  • List finalList = object1List.stream() .map(o -> o.getObject2List().stream().map(Object2::getNeedThisList).collect(Collectors.toList())) .flatMap(List::stream) .collect(Collectors.toList()); – meso Jul 23 '19 at 20:40
  • The documentation has examples: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#flatMap-java.util.function.Function-. Stream.flatMap() returns another Stream. You can once again use flatMap on that stream. – JB Nizet Jul 23 '19 at 20:40
  • You may also have an error in your code. The line after initializing `List object2List_2 = new ArrayList<>();`, do you mean to change `object2List.add(` to `object2List_2.add(` – Cuga Jul 23 '19 at 20:40
  • Don't use map(). use flatMap(). – JB Nizet Jul 23 '19 at 20:41
  • 1
    List finalList = object1List.stream() .flatMap(Object1::getObject2List) .flatMap(Object2::getNeedThisList) .collect(Collectors.toList()); – meso Jul 23 '19 at 20:43
  • 1
    @Cuga - You are right. Let me edit this. – meso Jul 23 '19 at 20:44

1 Answers1

1

Here's how it can work without Lombock.

public class Scratch {
    public static void main(String[] args) {
        List<List<String>> object2List = new ArrayList<>();
        object2List.add(List.of("good", "bad"));
        object2List.add(List.of("worse", "awesome"));

        List<List<String>> object2List_2 = new ArrayList<>();
        object2List_2.add(Arrays.asList("good1", "bad1"));
        object2List_2.add(Arrays.asList("worse1", "awesome1"));

        List<List<List<String>>> object1List = new ArrayList<>();
        object1List.add(object2List);
        object1List.add(object2List_2);

        // Please get me final list of all the Strings

        System.out.println(object1List.stream().flatMap((outer) -> outer.stream()).flatMap((mid) -> mid.stream()).collect(Collectors.toList()));
    }
}

Prints:

[good, bad, worse, awesome, good1, bad1, worse1, awesome1]

Edit

Re-reading the original post, if you want to retain the original lists (i.e., end up with a list of 4 lists) then you can do this:

System.out.println(object1List.stream().flatMap((outer) -> outer.stream()).collect(Collectors.toList()));

Which would print out:

[[good, bad], [worse, awesome], [good1, bad1], [worse1, awesome1]]
Cuga
  • 17,668
  • 31
  • 111
  • 166
  • 2
    `List.of` is Java 9, but if it is available, there is no reason to mix it with manual list construction, i.e. you can simply use `List> object2List = List.of(List.of("good", "bad")), List.of("worse", "awesome")), object2List_2 = List.of(List.of("good1", "bad1"), List.of("worse1", "awesome1")); List>> object1List = List.of(object2List, object2List_2);` – Holger Jul 24 '19 at 12:23