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

问题描述 投票:-1回答:2

我想用java 8中的reduce来计算文件中出现的单词任何帮助表示我不想使用收集器或映射到目前为止我的代码是;

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
java java-stream reduce
2个回答
1
投票

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

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()));

然后为了减少,你需要使用Map对象来减少(为了简洁起见,使用Java HashMap,这不是这种情况下最有效的数据结构):

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((word) -> singletonMap(word.toLowerCase(), 1L))
    .reduce(new HashMap<>(), (map1, map2) -> {
        for (Map.Entry<String, Long> entry: map2.entrySet()) {
            map1.put(entry.getKey(), map1.getOrDefault(entry.getKey(), 0L) + entry.getValue());
        }
        return 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;

0
投票

受@ 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;
    });

注意第二行创建一个模式,然后在流中使用该模式来分割行。

© www.soinside.com 2019 - 2024. All rights reserved.