Java 8 java 8中的限制和获取平面列表

Java 8 java 8中的限制和获取平面列表,java-8,Java 8,我有一个这样的物体 public class Keyword { private int id; private DateTime creationDate private int subjectId ... } 现在我有了如下的数据列表 关键词列表=[{1,'2018-10-20',10},{1,'2018-10-21',10},{1,'2018-10-22',10},{1,'2018-10-23',20},{1,'2018-10-24',20},{1,'2018-10-25

我有一个这样的物体

public class Keyword
{
  private int id;
  private DateTime creationDate
  private int subjectId
  ...
}
现在我有了如下的数据列表

关键词列表=[{1,'2018-10-20',10},{1,'2018-10-21',10},{1,'2018-10-22',10},{1,'2018-10-23',20},{1,'2018-10-24',20},{1,'2018-10-25',20},{1,'2018-10-26',30},{1,'2018-10-27',30},{1,'2018-10-28',40}]

我想限制主题id的列表

Ex:如果我提供限制为2,则应通过creationDate排序,仅包括每个受试者id的最新2条记录,并将结果作为列表返回。

resultList=关键词列表=[{1,'2018-10-21',10},{1,'2018-10-22',10},{1,'2018-10-24',20},{1,'2018-10-25',20},{1,'2018-10-26',30},{1,'2018-10-27',30},{1,'2018-10-28',40}]

我们如何在Java8中实现这种功能 我已经用这种方式实现了它。但我对这种代码的性能表示怀疑

dataList.stream()
        .collect(Collectors.groupingBy(Keyword::getSubjectId,
            Collectors.collectingAndThen(Collectors.toList(),
                myList-> myList.stream().sorted(Comparator.comparing(Keyword::getCreationDate).reversed()).limit(limit)
                    .collect(Collectors.toList()))))
        .values().stream().flatMap(List::stream).collect(Collectors.toList())

我想你可以分两步来做(假设
DateTime
具有可比性):

您的初始列表
.stream()
.collect(Collectors.groupingBy(关键字::getSubjectId));
列表结果=map.values()
.stream()
.flatMap(x->x.stream()
.sorted(Comparator.comparing(关键字::getCreationDate))
(1)限额(2)
.collect(Collectors.toList());
使用
收集器,这也可以在一个步骤中完成。我想先收集,然后再收集,但不确定它的可读性如何。

私有静态最终比较器按创建日期比较(k1,k2)->k2.getCreationDate().compareTo(k1.getCreationDate());
private static final Comparator<Keyword> COMPARE_BY_CREATION_DATE_DESC = (k1, k2) -> k2.getCreationDate().compareTo(k1.getCreationDate());

private static <T> Collector<T, ?, List<T>> limitingList(int limit) {
    return Collector.of(ArrayList::new,
            (l, e) -> {
                if (l.size() < limit)
                    l.add(e);
            },
            (l1, l2) -> {
                l1.addAll(l2.subList(0, Math.min(l2.size(), Math.max(0, limit - l1.size()))));
                return l1;
            }
    );
}

public static <R> Map<R, List<Keyword>> retrieveLast(List<Keyword> keywords, Function<Keyword, ? extends R> classifier, int limit) {
    return keywords.stream()
                   .sorted(COMPARE_BY_CREATION_DATE_DESC)
                   .collect(Collectors.groupingBy(classifier, limitingList(limit)));
}
专用静态收集器限制列表(整数限制){ 返回收集器.of(ArrayList::new, (l,e)->{ 如果(l.size()<限制) l、 加(e); }, (l1,l2)->{ addAll(l2.subList(0,Math.min(l2.size(),Math.max(0,limit-l1.size()))); 返回l1; } ); } publicstaticmap retrieveLast(列表关键字、函数分类器、int限制){ 返回关键字.stream() .排序(按创建日期比较) .collect(收集器.groupingBy(分类器,限制列表(限制))); }
以及客户代码:

List<Keyword> keywords = Collections.emptyList();
Map<Integer, List<Keyword>> map = retrieveLast(keywords, Keyword::getSubjectId, 2);
List关键字=Collections.emptyList();
Map Map=retrieveLast(关键字,关键字::getSubjectId,2);

我可以通过编写一些java-8代码来假设你尝试了什么?我可以假设
DateTime
org.joda.time.DateTime
…很可能是org.joda.time.DateTime这样的答案比我的努力更清楚。因为我的代码也给出了结果,但很难理解。你认为尤金怎么样?@Prabhath是的,看到了,事情是你正在收集一个
列表
,然后通过
flatMap
流式传输它。另外,如果你格式化你的代码,它会变得更清晰。是的,但我想按最新日期排序。所以我需要反转它并限制。是这样吗@Eugene@Prabhath你是在问我吗?对不起,我不明白您的意思,是的,您可以简单地将
反向
添加到比较器中,如果needed@Prabhath想举一个例子来说明你的真正意思吗?就像我们几天前讨论的那样冗长。。。不完全确定这是一个定制的收藏家我(强调我)想在这里。。。此外,您不必创建
按创建日期进行比较,您可以通过
比较器进行比较。比较
List<Keyword> keywords = Collections.emptyList();
Map<Integer, List<Keyword>> map = retrieveLast(keywords, Keyword::getSubjectId, 2);