EMottet EMottet - 1 year ago 46
Java Question

Java stream, replace foreach by collect

Is there a better way to fill my

zoo
with Java 8 stream ?

I guess there may be a solution using
map
/
flatMap
/
collect
?

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Main {

public static void main(String args[])
{
List<Animal> zoo = new ArrayList<>();

List<String> animals = new ArrayList<>();
animals.add("cat");
animals.add("dog");
animals.add("donkey");

Map<String, List<String>> houses = new ConcurrentHashMap<>();
houses.put("cat", Arrays.asList("white house", "black house"));
houses.put("dog", Arrays.asList("blue house"));
houses.put("donkey", Arrays.asList("black house"));

Map<String, List<String>> planets = new ConcurrentHashMap<>();
planets.put("white house", Arrays.asList("earth", "mars"));
planets.put("green house", Arrays.asList("earth", "jupiter"));
planets.put("blue house", Arrays.asList("jupiter", "mars"));
planets.put("black house", Arrays.asList("mars"));

animals.parallelStream().forEachOrdered(s ->
{
houses.get(s).parallelStream().forEachOrdered(s1 ->
{
System.out.println(s1);
planets.get(s1).parallelStream().forEachOrdered(s2 ->
{
zoo.add(new Animal(s, s1, s2));
}
);
}
);
}
);

System.out.println(zoo);

}

static class Animal {
private String name;
private String house;
private String planet;

Animal(String name, String house, String planet) {
this.name = name;
this.house = house;
this.planet = planet;
}

}
}

Answer Source

Try following solution:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class Main {

    public static void main(String args[]) {
        final List<String> animals = new ArrayList<>();
        animals.add("cat");
        animals.add("dog");
        animals.add("donkey");

        final Map<String, List<String>> houses = new ConcurrentHashMap<>();
        houses.put("cat", Arrays.asList("white house", "black house"));
        houses.put("dog", Arrays.asList("blue house"));
        houses.put("donkey", Arrays.asList("black house"));

        final Map<String, List<String>> planets = new ConcurrentHashMap<>();
        planets.put("white house", Arrays.asList("earth", "mars"));
        planets.put("green house", Arrays.asList("earth", "jupiter"));
        planets.put("blue house", Arrays.asList("jupiter", "mars"));
        planets.put("black house", Arrays.asList("mars"));

        final List<Animal> zoo = animals.parallelStream()
                .map(animal -> houses.getOrDefault(animal, Collections.emptyList())
                        .parallelStream()
                        .map(house -> planets.getOrDefault(house, Collections.emptyList())
                                .parallelStream()
                                .map(planet -> new Animal(animal, house, planet))
                                .collect(Collectors.toList())
                        )
                        .flatMap(Collection::stream)
                        .collect(Collectors.toList())
                )
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        zoo.forEach(System.out::println);
    }

    static final class Animal {
        private final String name;
        private final String house;
        private final String planet;

        Animal(String name, String house, String planet) {
            this.name = name;
            this.house = house;
            this.planet = planet;
        }

        @Override
        public String toString() {
            return "Animal{" +
                    "name='" + name + '\'' +
                    ", house='" + house + '\'' +
                    ", planet='" + planet + '\'' +
                    '}';
        }
    }
}

It prints following output to console:

Animal{name='cat', house='white house', planet='earth'}
Animal{name='cat', house='white house', planet='mars'}
Animal{name='cat', house='black house', planet='mars'}
Animal{name='dog', house='blue house', planet='jupiter'}
Animal{name='dog', house='blue house', planet='mars'}
Animal{name='donkey', house='black house', planet='mars'}

EDIT: I've updated the example to use more compact stream example.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download