使用流对内部对象的 Map 属性进行分组?
Using streams to group Map attributes from inner objects?
我正在学习 Java 8 - Java 11,我得到了一个正在转换为 java-streams 的代码。我有以下 类:
class Resource {
List<Capability> capabilities;
}
class Capability {
String namespace;
Map<String, Object> attributes;
}
我有一个资源流,我想从两个不同的命名空间("a"、"b")中提取它的所有功能属性到我确定可以做到的 Map<Resource, Map<String, Object>>
没有重复键。
我使用 map、flatMap 做了很多尝试,但是对于这些,我无法保留对主要资源对象的引用。使用 java9 的新功能我可以进步,但我被困在下面的代码中,我能够 return 所有属性,但在一个集合中。
我还不能按功能命名空间进行过滤,也无法将它们放入映射中:
Map<Resource, Set<Object>> result = pResolved.stream()
.collect(groupingBy(t -> t, flatMapping(
resource -> resource.getCapabilities(null).stream(),
flatMapping(
cap -> cap.getAttributes().entrySet().stream(),
toSet()))));
看来我走对了。
您可以使用 Collectors.toMap
作为 downstream
:
Map<Resource, Map<String, Object>> result = pResolved
.stream()
.collect(groupingBy(Function.identity(),
flatMapping(resource -> resource.getCapabilities().stream(),
flatMapping(cap -> cap.getAttributes().entrySet().stream(),
toMap(Map.Entry::getKey, Map.Entry::getValue)))));
还有一种方法只使用 java-8 方法:
Map<String, Set<Object>> result = pResolved.stream()
.map(Resource::getCapabilities) // Stream<List<Capability>>
.flatMap(List::stream) // Stream<Capability>
.collect(Collectors.toMap( // Map<String, Set<Object>>
c -> c.getNamespace(), // Key: String (namespace)
i -> new HashSet<>(i.getAttributes().values()))); // Value: Set of Map values
让我们假设样本输入是:
Resource [capabilities=[
Capability [namespace=a, attributes={a1=aa1, a2=aa2, a3=aa3}]]]
Resource [capabilities=[
Capability [namespace=b, attributes={b2=bb2, b3=bb3, b1=bb1}],
Capability [namespace=c, attributes={c3=cc3, c1=cc1, c2=cc2}]]]
那么上面的代码将导致:
a: [aa1, aa3, aa2]
b: [bb1, bb3, bb2]
c: [cc1, cc3, cc2]
我正在学习 Java 8 - Java 11,我得到了一个正在转换为 java-streams 的代码。我有以下 类:
class Resource {
List<Capability> capabilities;
}
class Capability {
String namespace;
Map<String, Object> attributes;
}
我有一个资源流,我想从两个不同的命名空间("a"、"b")中提取它的所有功能属性到我确定可以做到的 Map<Resource, Map<String, Object>>
没有重复键。
我使用 map、flatMap 做了很多尝试,但是对于这些,我无法保留对主要资源对象的引用。使用 java9 的新功能我可以进步,但我被困在下面的代码中,我能够 return 所有属性,但在一个集合中。 我还不能按功能命名空间进行过滤,也无法将它们放入映射中:
Map<Resource, Set<Object>> result = pResolved.stream()
.collect(groupingBy(t -> t, flatMapping(
resource -> resource.getCapabilities(null).stream(),
flatMapping(
cap -> cap.getAttributes().entrySet().stream(),
toSet()))));
看来我走对了。
您可以使用 Collectors.toMap
作为 downstream
:
Map<Resource, Map<String, Object>> result = pResolved
.stream()
.collect(groupingBy(Function.identity(),
flatMapping(resource -> resource.getCapabilities().stream(),
flatMapping(cap -> cap.getAttributes().entrySet().stream(),
toMap(Map.Entry::getKey, Map.Entry::getValue)))));
还有一种方法只使用 java-8 方法:
Map<String, Set<Object>> result = pResolved.stream()
.map(Resource::getCapabilities) // Stream<List<Capability>>
.flatMap(List::stream) // Stream<Capability>
.collect(Collectors.toMap( // Map<String, Set<Object>>
c -> c.getNamespace(), // Key: String (namespace)
i -> new HashSet<>(i.getAttributes().values()))); // Value: Set of Map values
让我们假设样本输入是:
Resource [capabilities=[
Capability [namespace=a, attributes={a1=aa1, a2=aa2, a3=aa3}]]]
Resource [capabilities=[
Capability [namespace=b, attributes={b2=bb2, b3=bb3, b1=bb1}],
Capability [namespace=c, attributes={c3=cc3, c1=cc1, c2=cc2}]]]
那么上面的代码将导致:
a: [aa1, aa3, aa2]
b: [bb1, bb3, bb2]
c: [cc1, cc3, cc2]