Java 8 使用 2 个字段排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45458256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 08:42:06  来源:igfitidea点击:

Java 8 Sort using 2 fields

javasortingjava-8java-stream

提问by Bharathiraja S

Based one some conditions, I have read data from MongoDB and creating a List<Document>with resultset.

基于一些条件,我已经从 MongoDB 读取数据并创建了一个List<Document>结果集。

List<Document> documentList = new ArrayList<Document>();

Sample Record Looks like:

示例记录看起来像:

documentList: [
    Document{
        { _id=5975ff00a213745b5e1a8ed9,
            u_id=,
            visblty = 1,
            c_id=5975ff00a213745b5e1a8ed8,                
            batchid=null,
            pdate=Tue Jul 11 17:52:25 IST 2017, 
            locale=en_US,
            subject = "Document2"
        }     },
    Document{
        { _id=597608aba213742554f537a6,
            u_id=,
            visblty = 1,
            c_id=597608aba213742554f537a3, 
            batchid=null,
            pdate=Fri Jul 28 01:26:22 IST 2017,
            locale=en_US,
            subject = "Document2"
        }    } 
]

Using this documentList, again i am filtering using some conditions and then I need to sort the filter record based on some conditions (which I will get in request).

使用此文档列表,我再次使用某些条件进行过滤,然后我需要根据某些条件(我将在请求中获得)对过滤器记录进行排序。

List<Document> outList = documentList.stream()
                .filter(d -> d.getInteger("visblty") == 1
                && (!StringUtils.isEmpty(req.pdate())? (d.getDate(CommonConstants.PDATE).after(afterDate)): true) 
                && (!StringUtils.isEmpty(req.pdate())? (d.getDate(CommonConstants.PDATE).before(beforeDate)): true)
                .sorted().skip(4).limit()
                .collect(Collectors.toList());

Not sure how to sorted (Dynamically needs to change the sorting order based on input, it looks like "pdate by DESC" or "subject by ASC")

不确定如何排序(动态需要根据输入更改排序顺序,它看起来像 " pdate by DESC" 或 " subject by ASC"

Like: "order by pdate DESC" or "order by pdate ASC"" or "order by subject DESC"

喜欢: "order by pdate DESC" or "order by pdate ASC"" or "order by subject DESC"

How to sort using Comparator object of Document class.

如何使用 Document 类的 Comparator 对象进行排序。

Note: I have tried couple of method which was suggested by the folks, but I didn't get any luck yet. Thank you in advance!

注意:我尝试了人们建议的几种方法,但我还没有运气。先感谢您!

回答by KayV

You can use group comparator and parallel stream as follows:

您可以按如下方式使用组比较器和并行流:

List<Document> outList = documentList.stream()
                               .filter(....)
                               .sorted(Comparator.comparing(Document::getPdate)
                                                 .thenComparing(Document::getSubject))   
                               .parallel();  

回答by M. Prokhorov

In terms of Java code, equivalent sorting comparators look like the following:

在 Java 代码方面,等效排序比较器如下所示:

  1. order by pdate

    Is represented by

    Comparator.comparing(Document::getPDate)
    
  2. order by subject

    Is represented by

    Comparator.comparing(Document::getSubject)
    
  3. order by pdate, subject

    Is represented by:

    Comparator.comparing(Document::getPDate).thenComparing(Document::getSubject)

  1. order by pdate

    Comparator.comparing(Document::getPDate)
    
  2. order by subject

    Comparator.comparing(Document::getSubject)
    
  3. order by pdate, subject

    代表为:

    Comparator.comparing(Document::getPDate).thenComparing(Document::getSubject)

If at any point you need to have descending order, you can call reversed()on comparator, like this:

如果在任何时候您需要降序,您可以调用reversed()比较器,如下所示:

Comparator.comparing(Document::getPDate).reversed()
          .thenComparing(Comparator.comparing(Document::getSubject).reversed())

Note, that thenComparingmethod is overridden, providing ability to pass in:

请注意,该thenComparing方法被覆盖,提供了传入的能力:

  • a Comparator
  • a Function-extractor (works if whatever function extracts is-a Comparable)
  • a Function and a Comparator(for when extracted value is not itself a Comparable, so you cannot use its natural order and have to specify how it should be compared.
  • 比较器
  • a Function-extractor (如果任何函数提取 is-a 则工作Comparable
  • 一个函数和一个比较器(因为当提取的值本身不是 a Comparable,所以你不能使用它的自然顺序,必须指定它应该如何比较。

回答by Szymon Stepniak

Instead of .sorted()try using .sorted(Comparator comparator)method.

而不是.sorted()尝试使用.sorted(Comparator comparator)方法。

You can create the Comparatorused with .sorted(comparator)by using Comparator.comparing():

您可以通过使用创建Comparatorused with :.sorted(comparator)Comparator.comparing()

Comparator.comparing(Function keyExtractor)
    .reversed()
    .thenComparing(Function keyExtractor)

for example:

例如:

List<Document> outList = documentList.stream()
         // do your filtering here
        .sorted(Comparator.comparing(Document::getPdate).reversed()
                .thenComparing(Document::getSubject))
        .skip(4)
        .limit()
        .collect(Collectors.toList());

In this example you can use method reference Document::getPdateand Document::getSubjectinstead of lambda expression like d -> d.getPdate()and d -> d.getSubject()

在这个例子中,你可以使用方法引用Document::getPdateDocument::getSubject而不是像d -> d.getPdate()和这样的 lambda 表达式d -> d.getSubject()