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);