Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.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迭代器中的合并映射_Java_Java 8_Java Stream - Fatal编程技术网

Java 8迭代器中的合并映射

Java 8迭代器中的合并映射,java,java-8,java-stream,Java,Java 8,Java Stream,我有一个文献库,在每次迭代中我都会创建一个新的地图 Map<String, List<String>> 我希望能收到一张地图 ["a",{"foo:a", "foo:a"}, "b",{"foo:b"}] 我尝试使用reduce函数,但因为putall仅在使用multimap而不是map时有效,所以它不是一个好选项 这是我的密码 public Map<String, List<String>> getMap(List<String>

我有一个文献库,在每次迭代中我都会创建一个新的地图

Map<String, List<String>>
我希望能收到一张地图

["a",{"foo:a", "foo:a"}, "b",{"foo:b"}]
我尝试使用reduce函数,但因为putall仅在使用multimap而不是map时有效,所以它不是一个好选项

这是我的密码

public Map<String, List<String>> getMap(List<String> items){
       return items().stream()
                .map(item -> getNewMap(item) --> Return a Map<String, List<String>>
                .reduce(new HashMap<>(), (o, p) -> {
                    o.putAll(p);
                    return o;
                });
}

public Map<String, List<String>> getNewMap(String item){
    Map<String, List<String>> map = new HashMap<>();
    map.put(item, Arrays.asList("foo:" + item));
    return map;
}       
publicmap-getMap(列表项){
返回项().stream()
.map(项目->getNewMap(项目)-->返回一个地图
.reduce(新的HashMap(),(o,p)->{
o、 普塔尔(p);
返回o;
});
}
公共映射getNewMap(字符串项){
Map Map=newhashmap();
map.put(item,array.asList(“foo:+item”);
返回图;
}       

我正在寻找一种无需详细说明的方法。

您想要的是将每个中间映射平面映射到它的条目,并从中生成一个映射

在下面的代码中,每个项目都被映射到它相应的映射。然后,每个映射被平面映射到它的条目,流被收集到一个映射中

public static void main(String[] args) {
    System.out.println(getMap(Arrays.asList("a", "a", "b")));
    // prints "{a=[foo:a, foo:a], b=[foo:b]}"
}

public static Map<String, List<String>> getMap(List<String> items) {
    return items.stream()
                .map(item -> getNewMap(item))
                .flatMap(m -> m.entrySet().stream())
                .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    Map.Entry::getValue,
                    (l1, l2) -> { List<String> l = new ArrayList<>(l1); l.addAll(l2); return l; }
                ));
}

public static Map<String, List<String>> getNewMap(String item) {
    Map<String, List<String>> map = new HashMap<>();
    map.put(item, Arrays.asList("foo:" + item));
    return map;
}
publicstaticvoidmain(字符串[]args){
System.out.println(getMap(Arrays.asList(“a”、“a”、“b”));
//打印“{a=[foo:a,foo:a],b=[foo:b]}”
}
公共静态映射getMap(列表项){
returnitems.stream()
.map(项目->getNewMap(项目))
.flatMap(m->m.entrySet().stream())
.collect(collector.toMap)(
Map.Entry::getKey,
Map.Entry::getValue,
(l1,l2)->{listl=newarraylist(l1);l.addAll(l2);返回l;}
));
}
公共静态映射getNewMap(字符串项){
Map Map=newhashmap();
map.put(item,array.asList(“foo:+item”);
返回图;
}

在多个键的情况下,这会将每个列表附加在一起。

每当您想要从流中获取
映射时,您应该首先检查如何适应。最简单的形式是,它接收一个分组函数,该函数确定结果映射的键,并将组中的所有元素收集到一个列表中。因为您需要efix
“foo:”
前面加了一个前缀,您必须在前面插入一个:

公共静态映射getMap(列表项){
return items.stream().collect(Collectors.groupingBy(
Function.identity(),
Collectors.mapping(“foo:::concat,Collectors.toList());
}

分类函数本身与标识函数一样微不足道,因为您希望所有相等的元素组成一个组。

生成映射只是为了将它们平面化,生成了令人印象深刻的代码,展示了流API的所有功能,但我认为OP的初始方法误导了您使用这种巴洛克式解决方案当你真正需要一个条目<代码> map < /C>时,考虑……霍格尔,你是正确的,对于这个特定的实例,可以做得更简单。但是如果内部映射是代码> [Fo::…,Bar:……],那该怎么办?
?考虑到问题中的输入和期望输出,不存在这种可能性。“内部映射”的存在不是任务的一部分,只是OP首次尝试解决问题的产物。初始输入是
“a”、“a”、“b”,我看不出有什么不同的前缀可以从那里来。“霍格尔HMM重新阅读修订版(第一个非常不清楚),我想我在XY问题中回答了Y。……请考虑接受霍格尔的解决方案而不是我的解决方案,它是更干净和更好的。谢谢新的解决方案。但是关于FoO:+项只是示例的一部分,实际上我们并没有在真正的代码中这样做。我会尽快查看此解决方案。无论您是否使用
“foo:::concat
x->“foo:+x
或任何您喜欢的映射函数,逻辑都不会改变。getNewMap()只是一个示例方法,实际应用程序返回一个带有更复杂业务逻辑的映射,因此Collector.mapping(函数)这看起来是不可能的。但是我会研究你的代码,看看是否可以使用它。再次感谢。然后你可能会过度简化你的问题。如果列表中可能有多个项目,而你想合并它们,你只需将此解决方案的
toList()
收集器替换为
collector.of(ArrayList::new,List::addAll,(l1,l2)->{l1.addAll(l2);返回l1;})
。如果地图可能有多个项目,您需要在
收集
之前执行一个
平面地图
步骤,类似于Tunaki的回答,但这仍然是可能的,无需创建中间
地图
。但要获得关于如何操作的具体答案,您需要一个更精确的问题…
public static void main(String[] args) {
    System.out.println(getMap(Arrays.asList("a", "a", "b")));
    // prints "{a=[foo:a, foo:a], b=[foo:b]}"
}

public static Map<String, List<String>> getMap(List<String> items) {
    return items.stream()
                .map(item -> getNewMap(item))
                .flatMap(m -> m.entrySet().stream())
                .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    Map.Entry::getValue,
                    (l1, l2) -> { List<String> l = new ArrayList<>(l1); l.addAll(l2); return l; }
                ));
}

public static Map<String, List<String>> getNewMap(String item) {
    Map<String, List<String>> map = new HashMap<>();
    map.put(item, Arrays.asList("foo:" + item));
    return map;
}
public static Map<String, List<String>> getMap(List<String> items) {
    return items.stream().collect(Collectors.groupingBy(
        Function.identity(),
        Collectors.mapping("foo:"::concat, Collectors.toList())));
}