有没有更好的方法用Java 8流填充zoo
?
我想可能有使用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 final 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;
}
}
}
答案 0 :(得分:2)
尝试以下解决方案:
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 + '\'' +
'}';
}
}
}
它将以下输出打印到控制台:
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'}
编辑:我已经更新了示例以使用更紧凑的流示例。
答案 1 :(得分:1)
如果你重新设计你的程序,也许你想要完成的任何事情都会更容易。我不知道你想要怎样对你的动物园做什么,但据我所知,你的代码意图是你的意图,房子和星球不是动物的属性,但行星是房子的容器,房子是动物的容器。因此,您可以使用字段Animal
定义一个类String name
,一个类House
,其中包含Collection<Animal>
子类型的字段似乎最合适(可能是List<Animal>
) ,以及类别为Planet
的字段的Collection<House>
类(在这种情况下,可能Set<House>
可能更合适,取决于您要执行的操作)。此外,House
需要检查它是否可以包含动物。如何最好地实施这取决于您的意图(例如,如果动物对房屋的适用性取决于动物本身,例如动物是否想要在特定的房屋中,则实施必须与适用性仅取决于房屋,例如,如果动物可以放入房屋内)。如果House
和/或Planet
直接实现Collection
并且不仅仅是包装器,它可能会更方便,但这又取决于您的意图。
我知道这不是您问题的直接答案,但也许它解决了导致问题首先出现的问题(但不知道代码的上下文,我无法确定当然)。