Java 8流filter – 基于排序的pdate

我试图在filter中对字段进行排序。

输入文件/样本记录:

DocumentList: [ Document{ { _id=5975ff00a213745b5e1a8ed9, u_id=, mailboxcontent_id=5975ff00a213745b5e1a8ed8, idmapping=Document{ {ptype=PDF, cid=00988, normalizedcid=00988, systeminstanceid=, sourceschemaname=, pid=0244810006} }, batchid=null, pdate=Tue Jul 11 17:52:25 IST 2017, locale=en_US } }, Document{ { _id=597608aba213742554f537a6, u_id=, mailboxcontent_id=597608aba213742554f537a3, idmapping=Document{ {platformtype=PDF, cid=00999, normalizedcid=00999, systeminstanceid=, sourceschemaname=, pid=0244810006} }, batchid=null, pdate=Fri Jul 28 01:26:22 IST 2017, locale=en_US } } ] 

在这里,我需要基于pdate进行排序。

 List outList = documentList.stream() .filter(p -> p.getInteger(CommonConstants.VISIBILITY) == 1) .parallel() .sequential() .collect(Collectors.toCollection(ArrayList::new)) .sort() .skip(skipValue) .limit(limtValue); 

不知道如何排序

 "order by pdate DESC" 

先感谢您!

您可以使用.sorted() Stream API方法:

 .sorted(Comparator.comparing(Document::getPDate).reversed()) 

完整的,重构的例子:

 List outList = documentList.stream() .filter(p -> p.getInteger(CommonConstants.VISIBILITY) == 1) .sorted(Comparator.comparing(Document::getPDate).reversed()) .skip(skipValue).limit(limtValue) .collect(Collectors.toCollection(ArrayList::new)) 

几件事要记住:

  • 如果您不关心List实现,请使用Collectors.toList()
  • collect()是一个终端操作,应该作为最后一个操作调用
  • .parallel().sequential()这完全没用 – 如果你想并行化,坚持.parallel()如果没有,不要写任何东西,默认情况.parallel()顺序
  • 为了排序,整个Stream将被加载到内存中

对于pivovarit的回答的替代方法,如果您的数据集可能太大而无法一次保留在内存中,这可能很有用(已排序的Stream必须在中间容器中维护整个底层数据集以提供正确排序的能力)。

我们不会在这里使用流排序操作:相反,我们将使用数据结构来保存我们告诉它的集合中的多个元素,并将根据排序标准推出额外的元素(我不声称在这里提供最佳实现,只是它的想法)。

为此,我们需要定制收集器:

 class SortedPileCollector implements Collector, List> { int maxSize; Comparator comptr; public SortedPileCollector(int maxSize, Comparator comparator) { if (maxSize < 1) { throw new IllegalArgumentException("Max size cannot be " + maxSize); } this.maxSize = maxSize; comptr = Objects.requireNonNull(comparator); } public Supplier> supplier() { return () -> new TreeSet<>(comptr); } public BiConsumer, E> accumulator() { return this::accumulate; // see below } public BinaryOperator> combiner() { return this::combine; } public Function, List> finisher() { return set -> new ArrayList<>(set); } public Set characteristics() { return EnumSet.of(Characteristics.UNORDERED); } // The interesting part public void accumulate(SortedSet set, E el) { Objects.requireNonNull(el); Objects.requireNonNull(set); if (set.size() < maxSize) { set.add(el); } else { if (set.contains(el)) { return; // we already have this element } E tailEl = set.last(); Comparator c = set.comparator(); if (c.compare(tailEl, el) <= 0) { // If we did not have capacity, received element would've gone to the end of our set. // However, since we are at capacity, we will skip the element return; } else { // We received element that we should preserve. // Remove set tail and add our new element. set.remove(tailEl); set.add(el); } } } public SortedSet combine(SortedSet first, SortedSet second) { SortedSet result = new TreeSet<>(first); second.forEach(el -> accumulate(result, el)); // inefficient, but hopefully you see the general idea. return result; } } 

上面的收集器充当管理有序数据集的可变结构。 请注意,此实现会忽略“重复”元素 – 如果要允许重复,则需要更改实现。

假设您需要三个顶级元素,请将此比较器用于您的情况:

 Comparator comparator = Comparator.comparing(Document::getPDate).reversed(); // see pivovarit's answer List = documentList.stream() .filter(p -> p.getInteger(VISIBILITY) == 1) .collect(new SortedPileCollector<>(3, comparator)); 

获得结果列表后,请执行此操作,假设Document.getPDate()返回pDate

Collections.sort(outList, Comparator.comparing(Document::getPDate).reversed());