Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8使用Collectors.toMap连接映射_Java_Java 8_Java Stream_Collectors - Fatal编程技术网

Java 8使用Collectors.toMap连接映射

Java 8使用Collectors.toMap连接映射,java,java-8,java-stream,collectors,Java,Java 8,Java Stream,Collectors,我试图在一个映射中收集进程的结果,一个对象列表,它返回一个映射。我想我应该和一个收藏家一起做。但是我还没有找到方法 代码如下: public class Car { List<VersionCar> versions; public List<VersionCar> getVersions() { return versions; } } public class VersionCar { private Stri

我试图在一个映射中收集进程的结果,一个对象列表,它返回一个映射。我想我应该和一个收藏家一起做。但是我还没有找到方法

代码如下:

public class Car {
    List<VersionCar> versions;
    public List<VersionCar> getVersions() {
        return versions;
      }
    }

public class VersionCar {
  private String wheelsKey;
  private String engineKey;
  public String getWheelsKey() {
     return wheelsKey;
  }
  public String getEngineKey() {
    return engineKey;
  }
}
公车{
列出版本;
公共列表getVersions(){
返回版本;
}
}
公共类VersionCar{
私人弦轮;
私有字符串引擎;
公共字符串getWheelsKey(){
返回轮;
}
公共字符串getEngineKey(){
返回引擎键;
}
}
处理方法:

private static Map<String,Set<String>> processObjects(VersionCar version) {
    Map<String,Set<String>> mapItems = new HashMap<>();
    mapItems.put("engine", new HashSet<>(Arrays.asList(version.getEngineKey())));
    mapItems.put("wheels", new HashSet<>(Arrays.asList(version.getWheelsKey())));
    return mapItems;
}
private静态映射processObjects(VersionCar版本){
Map mapItems=新的HashMap();
mapItems.put(“引擎”,新的哈希集(Arrays.asList(version.getEngineKey()));
mapItems.put(“wheels”,新哈希集(Arrays.asList(version.getWheelsKey()));
返回mapItems;
}
我的最终代码是:

Map<String,Set<String>> mapAllItems =
                car.getVersions().stream()
                   .map(versionCar -> processObjects(versionCar))
                   .collect(Collectors.toMap()); // here I don't know like collect the map.
地图项目=
car.getVersions().stream()
.map(versionCar->processObjects(versionCar))
.collect(Collectors.toMap());//这里我不知道我喜欢收集地图。

我的想法是处理版本列表,最后得到一个包含两个项目的地图:轮子和引擎,但是有一个包含所有版本的所有不同项目的集合。你有什么想法,我可以用Collectors.toMap或其他选项来实现吗

您可以使用收集器.toMap(键映射器、值映射器、合并函数)。最后一个参数用于解决与同一键关联的值之间的冲突

例如:

    Map<String, Set<String>> mapAllItems =
            car.getVersions().stream()
                    .map(versionCar -> processObjects(versionCar))
                    .flatMap(m -> m.entrySet().stream())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                            (firstSet, secondSet) -> {
                                    Set<String> result = new HashSet<>();
                                    result.addAll(firstSet);
                                    result.addAll(secondSet);
                                    return result;
                            }
                    ));
地图项目=
car.getVersions().stream()
.map(versionCar->processObjects(versionCar))
.flatMap(m->m.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,
(第一套,第二套)->{
Set result=new HashSet();
结果:addAll(第一组);
结果:addAll(第二组);
返回结果;
}
));

在这种情况下,您想要使用的运算符可能是“reduce”

car.getVersions().stream()
.map(versionCar->processObjects(versionCar))
.减少((map1,map2)->{
map2.forEach((键,子集)->map1.get(键).addAll(子集));
返回map1;
})
.orElse(新HashMap());
“reduce”中使用的lambda是一个二进制运算符,它合并2个映射并返回合并的映射

“orElse”只是在您的初始集合(版本)为空的情况下返回一些内容。
从类型的角度来看,为了获得
mapAllItems
,它去掉了“可选的”

,我们不需要也不应该定义
processObjects
方法:

Map<String, Set<String>> mapAllItems = new HashMap<>();
mapAllItems.put("engine", car.getVersions().stream().map(v -> v.getEngineKey()).collect(Collectors.toSet()));
mapAllItems.put("wheels", car.getVersions().stream().map(v -> v.getWheelsKey()).collect(Collectors.toSet()));

.map(…)
更改为
.flatMap(versionCar->processObjects(versionCar).entrySet().stream())
,然后使用
收集器.groupingBy(Entry::getKey,…)
。需要多一点,但这会让你找到正确的方向。谢谢Andreas,这对找到方法是一个很大的帮助。谢谢你的帮助Vlad,我一直在寻找。你可以使用lambda作为二进制运算符,而不是匿名内部类,它在IMO:
(s1,s2)->{s1.addAll(s2);返回s1;
。这需要将值映射器函数更改为
e->newhashset(e.getValue())
,以便在实际需要时不改变原始集。此外,我不认为需要在这里使用
flatMap
。只需使用
processObjects
返回的映射即可。当然,我知道lambdas),但要小心s1.addAll(…),因为可以将不可变集设置为参数之一,这比我选择的答案要干净得多!与本例无关,但当
map1
不包含
key
时,此代码将抛出NPE。同意,但正如您提到的,在本例中不可能。请记住,在map1中可能有NPE,我添加了此map2.forEach((key,subset)->{if(map1.get(key)!=null){map1.get(key).addAll(subset);}else{map1.put(key,subset);}});如果map2的键数实际上比map1的多,因为键在每个映射“引擎”和“轮子”因为它们是由processObjects生成的,所以NPE不应该发生。但当然,最好是安全的。
Map<String, Set<String>> mapAllItems = new HashMap<>();
mapAllItems.put("engine", car.getVersions().stream().map(v -> v.getEngineKey()).collect(Collectors.toSet()));
mapAllItems.put("wheels", car.getVersions().stream().map(v -> v.getWheelsKey()).collect(Collectors.toSet()));
mapAllItems = car.getVersions().stream()
    .flatMap(v -> Stream.of(new SimpleEntry<>("engine", v.getEngineKey()), new SimpleEntry<>("wheels", v.getWheelsKey())))
    .collect(Collectors.groupingBy(e -> e.getKey(), Collectors.mapping(e -> e.getValue(), Collectors.toSet())));