假设我有一个 List<Set<String>> 看起来是这样的:
List<Set<String>>
[A,B,C,D] [B,C,D,E] [C,D,E,F] [D,E,F,G]
如果我想使用每个值(a,b,c,d,e,f,g) Set<String> 在那里面 List<Set<String>> 通过Map它们来计算它们的发生率,对我来说,什么是实现它的好方法?我想让输出看起来像:
Set<String>
A: 1 B: 2 C: 3 D: 4 E: 3 F: 2 G: 1
r1zk6ea11#
只需将列表展平为单个流并使用 groupingBy 收藏家。首先,流式传输列表。这将创建一个较小的列表流。然后你需要流式传输。但你不需要4个字母流。您需要一个16个字母的流(或所有集合的总和)。flatmap就是这么做的。它将多个流扁平化为一个流。然后你要做一个频率计数。所以你想把字母作为键来分组。默认情况下 groupingBy 将创建一个列表并在列表中放置冲突(与重复键关联的值)。但你不想这样,所以 Collectors.counting() 如果你看到另一个已经存在的键,只需保持一个计数并将值更新1。所以你在数钥匙的出现次数。
groupingBy
Collectors.counting()
List<Set<String>> list = List.of(Set.of("A", "B", "C", "D"), Set.of("B", "C", "D", "E"), Set.of("C", "D", "E", "F"), Set.of("D", "E", "F", "G")); Map<String, Long> freq = list.stream().flatMap(Set::stream).collect(Collectors .groupingBy(a -> a, Collectors.counting())); freq.entrySet().forEach(System.out::println);
印刷品
A=1 B=2 C=3 D=4 E=3 F=2 G=1
下面是一个简单的默认示例 groupingBy 行为。它只是将值除以时基于它们的余数放入一个列表中 10 . IntStream 产生一股 int primitives 所以它们需要转换成一个对象( Integer 在这种情况下)。
10
IntStream
int primitives
Integer
Map<Integer, List<Integer>> remainders = IntStream.range(0, 100).mapToObj(Integer::valueOf) .collect(Collectors.groupingBy(n -> n % 10)); remainders.entrySet().forEach(System.out::println);
0=[0, 10, 20, 30, 40, 50, 60, 70, 80, 90] 1=[1, 11, 21, 31, 41, 51, 61, 71, 81, 91] 2=[2, 12, 22, 32, 42, 52, 62, 72, 82, 92] 3=[3, 13, 23, 33, 43, 53, 63, 73, 83, 93] 4=[4, 14, 24, 34, 44, 54, 64, 74, 84, 94] 5=[5, 15, 25, 35, 45, 55, 65, 75, 85, 95] 6=[6, 16, 26, 36, 46, 56, 66, 76, 86, 96] 7=[7, 17, 27, 37, 47, 57, 67, 77, 87, 97] 8=[8, 18, 28, 38, 48, 58, 68, 78, 88, 98] 9=[9, 19, 29, 39, 49, 59, 69, 79, 89, 99]
vsaztqbk2#
使用流api, flatMap 对于内部集合,应使用来获取字符串流,然后构建频率图:
flatMap
List<Set<String>> data = Arrays.asList( Set.of("A", "B", "C", "D"), Set.of("B", "C", "D", "E"), Set.of("C", "D", "E", "F"), Set.of("D", "E", "F", "G") ); data.stream() .flatMap(Set::stream) .collect(Collectors.toMap(s -> s, s -> 1, Integer::sum, LinkedHashMap::new)) .entrySet() .forEach(System.out::println);
输出:
izkcnapc3#
List<Set<String>> input = new ArrayList<>(); input.add(Set.of("A", "B", "C", "D")); input.add(Set.of("B", "C", "D", "E")); input.add(Set.of("C", "D", "E", "F")); input.add(Set.of("D", "E", "F", "G")); input.stream() .flatMap(Collection::stream) .collect(groupingBy(Function.identity(), counting())) .entrySet() .forEach(System.out::println);
导入
import java.util.*; import java.util.function.Function; import static java.util.stream.Collectors.counting; import static java.util.stream.Collectors.groupingBy;
3条答案
按热度按时间r1zk6ea11#
只需将列表展平为单个流并使用
groupingBy
收藏家。首先,流式传输列表。这将创建一个较小的列表流。
然后你需要流式传输。但你不需要4个字母流。您需要一个16个字母的流(或所有集合的总和)。flatmap就是这么做的。它将多个流扁平化为一个流。
然后你要做一个频率计数。所以你想把字母作为键来分组。默认情况下
groupingBy
将创建一个列表并在列表中放置冲突(与重复键关联的值)。但你不想这样,所以
Collectors.counting()
如果你看到另一个已经存在的键,只需保持一个计数并将值更新1。所以你在数钥匙的出现次数。印刷品
下面是一个简单的默认示例
groupingBy
行为。它只是将值除以时基于它们的余数放入一个列表中10
.IntStream
产生一股int primitives
所以它们需要转换成一个对象(Integer
在这种情况下)。印刷品
vsaztqbk2#
使用流api,
flatMap
对于内部集合,应使用来获取字符串流,然后构建频率图:输出:
izkcnapc3#
导入