组内的组的平均值 - 流

Bar*_*tek 4 java list java-8 java-stream

如何使用流计算组的平均值.下面的代码我想转换为流解决方案.

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();
}
Run Code Online (Sandbox Code Playgroud)

物品类:

public class Item {

    private String groupName;
    private Double value;

    // Full-args constructor
    // Getters and setters
}
Run Code Online (Sandbox Code Playgroud)

我试过这样的事情:

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();
}
Run Code Online (Sandbox Code Playgroud)

但方法总结平均值,所以不是我所期望的.如果可以通过分组恢复求和,则可以返回例外结果.

Eug*_*ene 5

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()));
Run Code Online (Sandbox Code Playgroud)

为了使其更具可读性,您可以在两个操作中执行此操作:

long distinct = items.stream().map(Item::getGroupName).distinct().count();
double sums = items.stream().mapToDouble(Item::getValue).sum();

System.out.println(sums / distinct);
Run Code Online (Sandbox Code Playgroud)

你可以一次性完成,但需要一个自定义收集器......

  • 第二个是更好的IMO (5认同)
  • 为第二种方法提供支持......第一种方法相对而言看起来过于复杂. (2认同)