Использование потоков для группировки атрибутов карты из внутренних объектов?
Я изучаю Java 8 - Java 11, и я получил код, который я конвертирую в потоки Java. У меня есть следующие классы:
class Resource {
List<Capability> capabilities;
}
class Capability {
String namespace;
Map<String, Object> attributes;
}
У меня есть поток ресурсов, и я хочу извлечь все атрибуты его возможностей из двух разных пространств имен ("a", "b") в Map<Resource, Map<String, Object>>
что я уверен, что не имеют дубликатов ключей.
Я сделал много попыток, используя карту, flatMap, но с этими, я не могу сохранить ссылку на основной объект ресурса. Используя новую функцию java9, я мог прогрессировать, но я застрял в приведенном ниже коде, где я смог вернуть все атрибуты, но в наборе. Я еще не смог отфильтровать по пространству имен возможностей, а также поместить их в карту:
Map<Resource, Set<Object>> result = pResolved.stream()
.collect(groupingBy(t -> t, flatMapping(
resource -> resource.getCapabilities(null).stream(),
flatMapping(
cap -> cap.getAttributes().entrySet().stream(),
toSet()))));
Кажется, я на правильном пути.
2 ответа
Вы могли бы вместо этого использовать 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]