Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested collections lambda iteration

Suppose I have an object containing a collection, each elements on the said collection contains a collection, and each collection contains a collection.

And I want to iterate on the deepest objects and apply the same code to it.

The imperative way is trivial, but is there a way to lambda-fy this all?

Here is how the code looks today:

My object o;
SecretType computedThingy = 78;
for (FirstLevelOfCollection coll : o.getList()) {
  for (SecondLevelOfCollection colColl : coll.getSet()) {
    for (MyCoolTinyObjects mcto : colColl.getFoo()) {
      mcto.setSecretValue(computedThingy);
    }
  }
}

I can see how to make a lambda out of the deepest loop:

colColl.getFoo().stream().forEach(x -> x.setSecretValue(computedThingy)

But can I do more?

like image 253
ptpdlc Avatar asked May 15 '17 14:05

ptpdlc


2 Answers

flatMap is available for such a purpose. What you get here is iteration over all elements of the various deepest collections as if they were a single collection:

o.getList().stream()
    .flatMap(c1 -> c1.getSet().stream())
    .flatMap(c2 -> c2.getFoo().stream())
    .forEach(x -> x.setSecretValue(computedThingy));
like image 155
Manos Nikolaidis Avatar answered Oct 16 '22 16:10

Manos Nikolaidis


flatMap to the rescue, simple example with a nested collection of String

See also: Java 8 Streams FlatMap method example

Turn a List of Lists into a List Using Lambdas

    Set<List<List<String>>> outerMostSet = new HashSet<>();
    List<List<String>> middleList = new ArrayList<>();
    List<String> innerMostList = new ArrayList<>();
    innerMostList.add("foo");
    innerMostList.add("bar");
    middleList.add(innerMostList);

    List<String> anotherInnerMostList = new ArrayList<>();
    anotherInnerMostList.add("another foo");

    middleList.add(anotherInnerMostList);
    outerMostSet.add(middleList);

    outerMostSet.stream()
                .flatMap(mid -> mid.stream())
                .flatMap(inner -> inner.stream())
                .forEach(System.out::println);

Produces

foo 
bar 
another foo
like image 3
Viktor Mellgren Avatar answered Oct 16 '22 15:10

Viktor Mellgren