Groupby,减少和排序对象列表

Groupby, reduce and sort for a list of objects

我有一个标签列表,其中包含每个标签的标签名称、标签类型、标签 ID、点击次数、订阅者、查看次数等几个属性。 tagName 和 tagType 可以为每个标签对象重复,而 tagId 对于每个标签都是唯一的。

我想执行这样的操作:

  1. Group/Aggregate tagName 和 tagType 组合的标签列表
  2. 对于每个组,我想针对 tagName 和 tagType 的每个组合将聚合列表缩减为单个元素。对于单个元素,tagId 与我无关,甚至可以设置为 null 或任何标记对象的 id。但是,我想在单个标签中汇总点击次数、订阅人数和观看次数。
  3. 最后,对于每个 tagName 和 tagType 的减少聚合的单个标签对象,我想根据用户指定的条件(如点击次数、订阅者或查看次数)和 return 前 5 个标签对象对它们进行排序。

为此,我的代码片段如下所示:

Map<TempClass, List<Tag>> aggregatedMap = tags.stream()
                        .collect(groupingBy(t -> new TempClass(t.getTagName(), t.getTagType()));

class Tag {
   String tagName;
   String tagType;
   String tagId;
   Long clicks;
   Long subscribers;
   Long views;
}

class TempClass {
   String tagName;
   String tagType;
}

Java 中的收集器是否可以做一些事情,或者我需要使用 for 循环来实现这个?

  public List<Tag> tags(List<Tag> input, long limit, Function<Tag, Long> extractor) {
    List<Tag> result =
            input
                    .stream()
                    .collect(Collectors.toMap(
                            x -> new TempClass()
                                    .setTagName(x.getTagName())
                                    .setTagType(x.getTagType()),
                            Function.identity(),
                            (left, right) -> {
                                left.setClicks(left.getClicks() + right.getClicks());
                                left.setSubscribers(left.getSubscribers() + right.getSubscribers());
                                left.setViews(left.getViews() + right.getViews());
                                return left;
                            }
                    ))
                    .values()
                    .stream()
                    .sorted(Comparator.comparing(extractor))
                    .limit(limit)
                    .collect(Collectors.toList());

    return result;
}

我稍微改变了你的TempClass

@EqualsAndHashCode
@Getter
@Setter
@Accessors(chain = true)
static class TempClass {
    String tagName;
    String tagType;
}

您需要 TempClass 才能根据 tagNametagType 获得 hashCode/equals。剩下的就没那么复杂了,恕我直言。