tkj*_*kja 11 java java-8 java-stream
我想使用Java Stream来运行POJO列表,例如List<A>
下面的列表,并将其转换为Map Map<String, Set<String>>
.
例如,A类是:
class A {
public String name;
public String property;
}
Run Code Online (Sandbox Code Playgroud)
我编写了下面的代码,将值收集到地图中Map<String, String>
:
final List<A> as = new ArrayList<>();
// the list as is populated ...
// works if there are no duplicates for name
final Map<String, String> m = as.stream().collect(Collectors.toMap(x -> x.name, x -> x.property));
Run Code Online (Sandbox Code Playgroud)
但是,因为可能有多个相同的POJO name
,我希望地图的值为a Set
.property
同一个键的所有字符串name
都应该放在同一个字符集中.
如何才能做到这一点?
// how do i create a stream such that all properties of the same name get into a set under the key name
final Map<String, Set<String>> m = ???
Run Code Online (Sandbox Code Playgroud)
Nev*_*vay 22
groupingBy完全符合你的要求:
import static java.util.stream.Collectors.*;
...
as.stream().collect(groupingBy((x) -> x.name, mapping((x) -> x.property, toSet())));
Run Code Online (Sandbox Code Playgroud)
@Nevay 的答案绝对是使用的正确方法groupingBy
,但也可以通过toMap
添加mergeFunction作为第三个参数来实现:
as.stream().collect(Collectors.toMap(x -> x.name,
x -> new HashSet<>(Arrays.asList(x.property)),
(x,y)->{x.addAll(y);return x;} ));
Run Code Online (Sandbox Code Playgroud)
此代码将数组映射到一个 Map,其中键为 as x.name
,值为 as,HashSet
其中一个值为x.property
。当存在重复的key/value时,则调用第三个参数合并函数来合并两个HashSet。
附言。如果你使用Apache Common库,你也可以使用它们SetUtils::union
作为合并