Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Sort using 2 fields

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

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

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

How to sort using Comparator object of Document class.

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!

like image 272
Bharathiraja S Avatar asked Aug 02 '17 10:08

Bharathiraja S


2 Answers

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();  
like image 121
KayV Avatar answered Oct 19 '22 23:10

KayV


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

  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)

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

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

Note, that thenComparing method is overridden, providing ability to pass in:

  • 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.
like image 37
M. Prokhorov Avatar answered Oct 19 '22 23:10

M. Prokhorov