元素可以属于多个组的流分组
Stream grouping where elements can belong to more than one group
我正在尝试使用流 api 分组收集器来获取映射 groupId -> List of elements
。我的案例的特别之处在于一个元素可以属于多个组。
用一个简单的例子来演示:假设我想使用数字 2 - 10
作为分组的标识符,并希望将数字 2 - 40
分组,以便它们可以被视为我的标识符。传统上我会这样做:
Map<Integer,List<Integer>> map = new HashMap<>();
for(int i = 2; i < 11; i++){
for(int j = 2; j < 41; j++){
if(j%i == 0)
map.computeIfAbsent(i, k -> new ArrayList<>()).add(j);
}
}
map.forEach((k,v) -> {
System.out.println(k + " : " + v);
});
得到类似
的东西
2 : [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]
3 : [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39]
4 : [4, 8, 12, 16, 20, 24, 28, 32, 36, 40]
5 : [5, 10, 15, 20, 25, 30, 35, 40]
6 : [6, 12, 18, 24, 30, 36]
7 : [7, 14, 21, 28, 35]
8 : [8, 16, 24, 32, 40]
9 : [9, 18, 27, 36]
10 : [10, 20, 30, 40]
为了使用流来做到这一点,我尝试将 问题的答案应用到我的案例中,但没有成功。
IntStream.range(2, 11).boxed()
.flatMap(g -> IntStream.range(2, 41)
.boxed()
.filter(i -> i%g == 0)
.map(i -> new AbstractMap.SimpleEntry<>(g,i))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList()))));
我遇到编译错误
incompatible types: inference variable R#1 has incompatible bounds
equality constraints: Map<K,D>
lower bounds: Stream<? extends R#2>,Object
where R#1,A#1,T#1,K,T#2,A#2,D,R#2 are type-variables:
R#1 extends Object declared in method <R#1,A#1>collect(Collector<? super T#1,A#1,R#1>)
A#1 extends Object declared in method <R#1,A#1>collect(Collector<? super T#1,A#1,R#1>)
T#1 extends Object declared in interface Stream
K extends Object declared in method <T#2,K,A#2,D>groupingBy(Function<? super T#2,? extends K>,Collector<? super T#2,A#2,D>)
T#2 extends Object declared in method <T#2,K,A#2,D>groupingBy(Function<? super T#2,? extends K>,Collector<? super T#2,A#2,D>)
A#2 extends Object declared in method <T#2,K,A#2,D>groupingBy(Function<? super T#2,? extends K>,Collector<? super T#2,A#2,D>)
D extends Object declared in method <T#2,K,A#2,D>groupingBy(Function<? super T#2,? extends K>,Collector<? super T#2,A#2,D>)
R#2 extends Object declared in method <R#2>flatMap(Function<? super T#1,? extends Stream<? extends R#2>>)
我做错了什么?
请注意,我的原始案例不是将数字分配给它们的倍数。实际上,我的组 ID 具有很长的值,并且列表包含自定义对象。但是当我解决了上面的例子时,我想我可以将它应用到我的案例中。我只是想用简单的方式描述问题
你的意思是这样的?
Map<Integer,List<Integer>> v = IntStream.range(2, 11).boxed()
.map(g -> IntStream.range(2, 41)
.boxed()
.filter(i -> i % g == 0)
.map(i -> new AbstractMap.SimpleEntry<>(g, i))
.collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey,
Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList()))))
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
我正在尝试使用流 api 分组收集器来获取映射 groupId -> List of elements
。我的案例的特别之处在于一个元素可以属于多个组。
用一个简单的例子来演示:假设我想使用数字 2 - 10
作为分组的标识符,并希望将数字 2 - 40
分组,以便它们可以被视为我的标识符。传统上我会这样做:
Map<Integer,List<Integer>> map = new HashMap<>();
for(int i = 2; i < 11; i++){
for(int j = 2; j < 41; j++){
if(j%i == 0)
map.computeIfAbsent(i, k -> new ArrayList<>()).add(j);
}
}
map.forEach((k,v) -> {
System.out.println(k + " : " + v);
});
得到类似
的东西2 : [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]
3 : [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39]
4 : [4, 8, 12, 16, 20, 24, 28, 32, 36, 40]
5 : [5, 10, 15, 20, 25, 30, 35, 40]
6 : [6, 12, 18, 24, 30, 36]
7 : [7, 14, 21, 28, 35]
8 : [8, 16, 24, 32, 40]
9 : [9, 18, 27, 36]
10 : [10, 20, 30, 40]
为了使用流来做到这一点,我尝试将
IntStream.range(2, 11).boxed()
.flatMap(g -> IntStream.range(2, 41)
.boxed()
.filter(i -> i%g == 0)
.map(i -> new AbstractMap.SimpleEntry<>(g,i))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList()))));
我遇到编译错误
incompatible types: inference variable R#1 has incompatible bounds equality constraints: Map<K,D> lower bounds: Stream<? extends R#2>,Object where R#1,A#1,T#1,K,T#2,A#2,D,R#2 are type-variables: R#1 extends Object declared in method <R#1,A#1>collect(Collector<? super T#1,A#1,R#1>) A#1 extends Object declared in method <R#1,A#1>collect(Collector<? super T#1,A#1,R#1>) T#1 extends Object declared in interface Stream K extends Object declared in method <T#2,K,A#2,D>groupingBy(Function<? super T#2,? extends K>,Collector<? super T#2,A#2,D>) T#2 extends Object declared in method <T#2,K,A#2,D>groupingBy(Function<? super T#2,? extends K>,Collector<? super T#2,A#2,D>) A#2 extends Object declared in method <T#2,K,A#2,D>groupingBy(Function<? super T#2,? extends K>,Collector<? super T#2,A#2,D>) D extends Object declared in method <T#2,K,A#2,D>groupingBy(Function<? super T#2,? extends K>,Collector<? super T#2,A#2,D>) R#2 extends Object declared in method <R#2>flatMap(Function<? super T#1,? extends Stream<? extends R#2>>)
我做错了什么?
请注意,我的原始案例不是将数字分配给它们的倍数。实际上,我的组 ID 具有很长的值,并且列表包含自定义对象。但是当我解决了上面的例子时,我想我可以将它应用到我的案例中。我只是想用简单的方式描述问题
你的意思是这样的?
Map<Integer,List<Integer>> v = IntStream.range(2, 11).boxed()
.map(g -> IntStream.range(2, 41)
.boxed()
.filter(i -> i % g == 0)
.map(i -> new AbstractMap.SimpleEntry<>(g, i))
.collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey,
Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList()))))
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));