使用reduce方法计算Java8文件中的单词数

使用reduce方法计算Java8文件中的单词数,java,java-stream,reduce,Java,Java Stream,Reduce,我想用reduce在java8中计算word在文件中的出现,感谢任何帮助,我不想使用收集器或Map,因为我的代码是 filecontent.flatMap(line->Stream.of(line.split("\\s+"))) .map(String::toLowerCase) .collect(Collectors.groupingBy(Function.identity(), Collecto

我想用reduce在java8中计算word在文件中的出现,感谢任何帮助,我不想使用收集器或Map,因为我的代码是

filecontent.flatMap(line->Stream.of(line.split("\\s+")))
                       .map(String::toLowerCase)
                       .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));   
  //here I want to replace colect() with reduce

首先,您应该在问题中提供一个完整的可编译示例,如:

Stream<String> filecontent = Stream.of("foo in bar is foo", "bar in bar is not foo");
Map<String, Long> result = filecontent.flatMap(line -> Stream.of(line.split("\\s+")))
    .map(String::toLowerCase)
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Stream filecontent=Stream.of(“条中的foo是foo”,“条中的bar不是foo”);
映射结果=filecontent.flatMap(line->Stream.of(line.split(\\s+)))
.map(字符串::toLowerCase)
.collect(Collectors.groupingBy(Function.identity()、Collectors.counting());
然后,为了减少,您需要使用映射对象来减少(为了简洁起见,使用Java HashMap,这不是本例中最有效的数据结构):

Stream filecontent=Stream.of(“条中的foo是foo”,“条中的bar不是foo”);
映射结果=filecontent.flatMap(line->Stream.of(line.split(\\s+)))
.map((word)->singletonMap(word.toLowerCase(),1L))
.reduce(新的HashMap(),(map1,map2)->{
对于(Map.Entry:map2.entrySet()){
put(entry.getKey(),map1.getOrDefault(entry.getKey(),0L)+entry.getValue());
}
返回map1;
});
这将首先创建一个新的空HashMap,然后为每个新词创建一个单例HashMap,并在每个reduce步骤中将这样的单例映射合并到原始HashMap中。如果要使用并行流执行此操作,则需要在reduce步骤中创建一个新映射:

        Map<String, Long> tempResult = new HashMap<>(map1);
        for (Map.Entry<String, Long> entry: map2.entrySet()) {
            tempResult.put(entry.getKey(), map1.getOrDefault(entry.getKey(), 0L) + entry.getValue());
        }
        return tempResult;
Map tempResult=newhashmap(map1);
对于(Map.Entry:map2.entrySet()){
tempResult.put(entry.getKey(),map1.getOrDefault(entry.getKey(),0L)+entry.getValue());
}
返回结果;

受@tkruse答案的启发,我想出了以下片段:

Stream<String> fileContent = Stream.of("foo in bar is foo", "bar in bar is not foo");
Pattern pattern = Pattern.compile("\\s+");
Map<String, Long> result = fileContent
    .flatMap(pattern::splitAsStream)
    .reduce(new HashMap<String, Long>(), (map, word) -> {
        map.merge(word, 1L, Long::sum);
        return map;
    }, (left, right) -> {
        right.forEach((key , count ) -> left.merge(key, count, Long::sum));
        return left;
    });
Stream fileContent=Stream.of(“条中的foo是foo”,“条中的bar不是foo”);
Pattern=Pattern.compile(\\s+);
映射结果=文件内容
.flatMap(模式::拆分流)
.reduce(新HashMap(),(map,word)->{
合并(字,1L,长::和);
返回图;
},(左,右)->{
right.forEach((key,count)->left.merge(key,count,Long::sum));
左转;
});

请注意第二行,它创建了一个模式,然后在流中使用该模式来分割这些行

collect()
工作正常时,你为什么要使用
reduce()
呢?我只想@daniu像谷歌地图一样使用它,reduce我没有这种动机。但是,是的,如果我看答案,人们似乎找到了一种方法。不要使用数组。asList(…).stream()直接使用
stream.of(…)
Stream<String> fileContent = Stream.of("foo in bar is foo", "bar in bar is not foo");
Pattern pattern = Pattern.compile("\\s+");
Map<String, Long> result = fileContent
    .flatMap(pattern::splitAsStream)
    .reduce(new HashMap<String, Long>(), (map, word) -> {
        map.merge(word, 1L, Long::sum);
        return map;
    }, (left, right) -> {
        right.forEach((key , count ) -> left.merge(key, count, Long::sum));
        return left;
    });