Bartek:
Cómo calcular un valor promedio para el grupo utilizando corriente. A continuación código que me gustaría para transformar a la solución de flujo.
public static void main(String[] args) {
List<Item> items = Arrays.asList(
new Item("A", 1.0),
new Item("A", 1.0),
new Item("B", 1.0)
);
System.out.println(averageForGroup(items));
}
public static double averageForGroup(List<Item> items) {
Set<String> uniqueGroups = new HashSet<>();
double sum = 0;
for (Item i : items) {
String groupName = i.getGroupName();
if (!uniqueGroups.contains(groupName)) {
uniqueGroups.add(groupName);
}
sum += i.getValue();
}
return sum / uniqueGroups.size();
}
la clase de artículo:
public class Item {
private String groupName;
private Double value;
// Full-args constructor
// Getters and setters
}
He intentado algo como esto:
public static double averageForGroup2(List<Item> items) {
return items.stream()
.collect(Collectors.groupingBy(
Item::getGroupName,
Collectors.averagingDouble(Item::getValue)) )
.entrySet().stream()
.mapToDouble(entry -> entry.getValue())
.sum();
}
Pero el método resume las medias, por lo que no es lo que esperamos. Si era posible revertir sumando con la agrupación puede devolver resultado exceptuados.
Eugene:
double result = items.stream()
.collect(
Collectors.collectingAndThen(
Collectors.groupingBy(
Item::getGroupName,
Collectors.summingDouble(Item::getValue)),
map -> map.values().stream().mapToDouble(Double::doubleValue).sum() / map.size()));
Para que sea más fácil de leer, puede hacerlo en dos operaciones:
long distinct = items.stream().map(Item::getGroupName).distinct().count();
double sums = items.stream().mapToDouble(Item::getValue).sum();
System.out.println(sums / distinct);
Puede hacerlo de una sola pasada, sino que requiere un colector a medida ...