【问题标题】:java8 stream grouping and sorting on aggregate sumjava8流分组和聚合总和排序
【发布时间】:2015-08-24 07:56:13
【问题描述】:

给定一个java类Something

class Something {
  private int parentKey;
  private String parentName;
  private int childKey;
  private int noThings;

  public Something(int parentKey, String parentName, int childKey, 
    int noThings) {
    this.parentKey = parentKey;
    this.parentName = parentName;
    this.childKey = childKey;
    this.noThings = noThings;
  }

  public int getParentKey() {
    return this.parentKey;
  }

  public int getNoThings() {
    return this.noThings;
  }
}

我有一个对象列表

List<Something> somethings = newArrayList(
            new Something(425, "Lemon", 44, 23),
            new Something(123, "Orange", 125, 66),
            new Something(425, "Lemon", 11, 62),
            new Something(123, "Orange", 126, 32),
            new Something(323, "Lime", 25, 101),
            new Something(123, "Orange", 124, 88)
);

我希望能够对它们进行排序,以便它们按每个父对象的 noThings 的累积总和然后按 noThings 排序。

所以我最终得到了

List<Something> sortedSomethings = newArrayList(
            new Something(123, "Orange", 124, 88),
            new Something(123, "Orange", 125, 66),
            new Something(123, "Orange", 126, 32),
            new Something(323, "Lime", 25, 101),
            new Something(425, "Lemon", 11, 62),
            new Something(425, "Lemon", 44, 23)
);

我知道通过 parentKey 映射它并且 noThings 的总和是

Map<Integer, Integer> totalNoThings = colns
            .stream()
            .collect(
                    Collectors.groupingBy(
                            Something::getParentKey,
            Collectors.summingInt(ClientCollectionsReceived::getNoThings)));

我认为也许包装我的 Something 类并拥有每个父键的总数可能会以某种方式起作用。

class SomethingWrapper {
  private int totalNoThingsPerClient;
  private Something something;
}

但看起来工作量很大,而且不是很优雅。

任何意见/想法将不胜感激。

【问题讨论】:

    标签: java-8 grouping aggregate java-stream


    【解决方案1】:

    实际上不得不做一个小调整,而不是totalNoThings.get,它是totalNothings.indexOf

    所以最终解决方案。是

    List<Integer> totalNoThings
        = somethings.stream()
        .collect(Collectors.groupingBy(Something::getParentKey,
                        Collectors.summingInt(Something::getNoThings)))
        .entrySet().stream()
        .sorted(Map.Entry.comparingByValue())
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());
    
    
    List<Something> sorted 
        = somethings.stream().sorted(
                Comparator.comparing(
                (Something obj)->totalNoThings.indexOf(
                obj.getParentKey()))
        .thenComparing(Something::getNoThings).reversed())
                .collect(Collectors.toList());
    

    【讨论】:

      【解决方案2】:

      嗯,你已经通过收集汇总信息完成了主要工作

      Map<Integer, Integer> totalNoThings = somethings.stream()
          .collect(Collectors.groupingBy(Something::getParentKey,
              Collectors.summingInt(Something::getNoThings)));
      

      那么您需要做的就是在排序操作中利用这些信息:

      List<Something> sorted=somethings.stream().sorted(
          Comparator.comparing((Something x)->totalNoThings.get(x.getParentKey()))
                .thenComparing(Something::getNoThings).reversed())
          .collect(Collectors.toList());
      

      【讨论】:

      • 谢谢!经过一些代码摔跤后,我正要发布答案!我的解决方案不如你的好,但遵循相同的逻辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-05
      • 1970-01-01
      • 1970-01-01
      • 2022-01-26
      • 2014-02-07
      • 2013-02-03
      相关资源
      最近更新 更多