Java 映射中特定键的值之和

Java 映射中特定键的值之和,java,hashmap,refactoring,java-8,java-stream,Java,Hashmap,Refactoring,Java 8,Java Stream,我有一个文本文件,其中每一行包含一对名称和金额,如下所示: Mike 5 Kate 2 Mike 3 我需要按键对这些值求和。我就是这样解决的 public static void main(String[] args) { Map<String, Integer> map = new HashMap<String, Integer>(); try { Files.lines(Paths.get("/Users/walter/Deskto

我有一个文本文件,其中每一行包含一对名称和金额,如下所示:

Mike 5
Kate 2
Mike 3
我需要按键对这些值求和。我就是这样解决的

public static void main(String[] args) {
    Map<String, Integer> map = new HashMap<String, Integer>();
    try {
        Files.lines(Paths.get("/Users/walter/Desktop/stuff.txt"))
                .map(line -> line.split("\\s+")).forEach(line -> {
                    String key = line[0];
                    if (map.containsKey(key)) {
                        Integer oldValue = map.get(key);
                        map.put(key, oldValue + Integer.parseInt(line[1]));
                    } else {
                        map.put(line[0], Integer.parseInt(line[1]));
                    }
                });
        map.forEach((k,v) -> System.out.println(k + " " +v));

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    ;

}
publicstaticvoidmain(字符串[]args){
Map Map=newhashmap();
试一试{
Files.line(path.get(“/Users/walter/Desktop/stuff.txt”))
.map(行->行.split(\\s+)).forEach(行->{
字符串键=行[0];
if(地图容器(图例)){
整数oldValue=map.get(键);
map.put(key,oldValue+Integer.parseInt(第[1]行));
}否则{
map.put(第[0]行),Integer.parseInt(第[1]行);
}
});
map.forEach((k,v)->System.out.println(k+“”+v));
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
;
}

实际上,我如何才能以更实用的方式改进此代码,使其能够更并发地处理数据(使用并行流等)。

当您想要编写功能代码时,规则是:不要使用
forEach
。这是一个必要的解决方案,它破坏了功能代码

您需要的是按第一部分(键)拆分每一行和分组,同时对第二部分(值)求和:


这将使用键
行[0]
和值
Integer.valueOf(行[1])
放置一个新值,如果该键不存在,否则,它将使用给定的重新映射函数(在这种情况下是新旧值之和)更新该键。

解释得很好!那么这个例子中的并发处理(并行流用法)呢?@Gerardrozavolgyi我不确定读取文件中的行是否能够很好地并行化,但这只是在流管道上调用
parallel()
的问题。也许收集列表中的所有行并调用该列表上的
parallelStream()
,以按行的第一部分对其进行分组会更好。
Map<String, Integer> map = 
    Files.lines(Paths.get("/Users/walter/Desktop/stuff.txt"))
         .map(s -> s.split("\\s+"))
         .collect(groupingBy(a -> a[0], summingInt(a -> Integer.parseInt(a[1]))));
map.merge(line[0], Integer.valueOf(line[1]), Integer::sum);