Soy bastante nuevo en movimiento Java desde C #. Tengo la siguiente clase.
class Resource {
String name;
String category;
String component;
String group;
}
Quiero saber los números siguientes: 1. Recuento de los recursos en la categoría. 2. recuento diferente de los componentes en cada categoría. (Nombres de los componentes pueden ser duplicado) 3. conde de recursos agrupados por categoría y grupo.
Yo era capaz de conseguir un poco de éxito en el uso Collectors.groupingBy
. Sin embargo, el resultado es siempre así.
Map<String, List<Resource>>
Para obtener la cuenta de que tengo que analizar el conjunto de claves y calcular los tamaños. Utilizando c # linq, puedo calcular fácilmente todos los parámetros anteriormente citados. Estoy asumiendo que definitivamente hay una mejor manera de hacer esto en Java también. Por favor avise.
Para # 1, me gustaría usar Collectors.groupingBy
junto con Collectors.counting
:
Map<String, Long> resourcesByCategoryCount = resources.stream()
.collect(Collectors.groupingBy(
Resource::getCategory,
Collectors.counting()));
Esto agrupa Resource
elementos por category
, conteo de cuántos de ellos pertenecen a cada categoría.
Para # 2, yo no usaría corrientes. En su lugar, que haría uso de la Map.computeIfAbsent
operación (introducido en Java 8):
Map<String, Set<String>> distinctComponentsByCategory = new LinkedHashMap<>();
resources.forEach(r -> distinctComponentsByCategory.computeIfAbsent(
r.getCategory(),
k -> new HashSet<>())
.add(r.getGroup()));
Esta primera crea una LinkedHashMap
(que conserva orden de inserción ). A continuación, Resource
los elementos son iterados y puestos en este mapa de tal manera que se agrupan por category
y cada una group
se añade a una HashSet
que se asigna a cada categoría. Como conjuntos no permiten duplicados, no habrá grupos duplicados de cualquier categoría. A continuación, el recuento distinto de los grupos es el tamaño de cada conjunto.
Para # 3, que haría uso de nuevo Collectors.groupingBy
junto con Collectors.counting
, pero que haría uso de una clave compuesta para agrupar por:
Map<List<String>, Long> resourcesByCategoryAndGroup = resources.stream()
.collect(Collectors.groupingBy(
r -> Arrays.asList(r.getCategory(), r.getGroup()), // or List.of
Collectors.counting()));
Esto agrupa Resource
elementos por category
y group
, conteo de cuántos de ellos pertenecen a cada (category, group)
par. Para la clave de agrupación, una de dos elementos List<String>
está siendo utilizado, con el category
siendo su elemento y el primero component
siendo su segundo elemento.
O bien, en lugar de utilizar una clave compuesta, se puede utilizar agrupación anidada:
Map<String, Map<String, Long>> resourcesByCategoryAndGroup = resources.stream()
.collect(Collectors.groupingBy(
Resource::getCategory,
Collectors.groupingBy(
Resource::getGroup,
Collectors.counting())));