我希望将流中的项目收集到一个映射中,将相等的对象分组在一起,并映射到出现次数。
List<String> list = Arrays.asList("Hello", "Hello", "World");
Map<String, Long> wordToFrequency = // what goes here?
所以在这种情况下,我希望地图由以下条目组成:
Hello -> 2
World -> 1
我该怎么做呢?
我希望将流中的项目收集到一个映射中,将相等的对象分组在一起,并映射到出现次数。
List<String> list = Arrays.asList("Hello", "Hello", "World");
Map<String, Long> wordToFrequency = // what goes here?
所以在这种情况下,我希望地图由以下条目组成:
Hello -> 2
World -> 1
我该怎么做呢?
我认为你只是在寻找另一个Collector
的重载,用于指定对每个组执行什么操作... 然后使用Collectors.counting()
进行计数:
import java.util.*;
import java.util.stream.*;
class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Hello");
list.add("World");
Map<String, Long> counted = list.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted);
}
}
结果:
{Hello=2, World=1}
(还有一种使用groupingByConcurrent
更高效的可能性。如果在上下文中安全,这是您真正代码要记住的事情。)
这是一个对象列表的例子。
Map<String, Long> requirementCountMap = requirements.stream().collect(Collectors.groupingBy(Requirement::getRequirementType, Collectors.counting()));
以下是实现当前任务的稍微不同的选项。
使用toMap
:
list.stream()
.collect(Collectors.toMap(Function.identity(), e -> 1, Math::addExact));
使用 Map::merge
:
Map<String, Integer> accumulator = new HashMap<>();
list.forEach(s -> accumulator.merge(s, 1, Math::addExact));
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Hello");
list.add("World");
Map<String, List<String>> collect = list.stream()
.collect(Collectors.groupingBy(o -> o));
collect.entrySet()
.forEach(e -> System.out.println(e.getKey() + " - " + e.getValue().size()));
StreamEx 提供了以下解决方案:
StreamEx.of(list).groupingBy(Function.identity(), MoreCollectors.countingInt());
collect(Collectors.
Collectors2
类来将List
转换为Bag
,使用Stream
。Bag
是一种专门用于计数的数据结构。Bag<String> counted =
list.stream().collect(Collectors2.countBy(each -> each));
Assert.assertEquals(1, counted.occurrencesOf("World"));
Assert.assertEquals(2, counted.occurrencesOf("Hello"));
System.out.println(counted.toStringOfItemToCount());
输出:
{World=1, Hello=2}
List
收集到一个 Bag
中。Bag<String> counted =
list.stream().collect(Collectors2.toBag());
Bag<String> counted = Lists.adapt(list).countBy(each -> each);
Bag<String> counted = Lists.adapt(list).toBag();
Bag<String> counted = Bags.mutable.with("Hello", "Hello", "World");
然后使用指定的downstream Collector对与给定键关联的值执行减少操作
- Muhammad Hewedy