web-dev-qa-db-fra.com

Java 8 Trier en utilisant 2 champs

Sur la base de certaines conditions, j'ai lu les données de MongoDB et créé un List<Document> avec l'ensemble de résultats.

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

Exemple d'enregistrement ressemble à:

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"
        }    } 
]

En utilisant cette liste de documents, encore une fois, je filtre en utilisant certaines conditions, puis je dois trier l'enregistrement du filtre en fonction de certaines conditions (que j'obtiendrai à la demande).

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

Je ne sais pas comment trier (doit dynamiquement changer l'ordre de tri en fonction de l'entrée, il ressemble à "pdate by DESC" ou "subject by ASC")

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

Comment trier à l'aide de l'objet Comparateur de la classe Document.

Remarque: J'ai essayé quelques méthodes suggérées par les gens, mais je n'ai pas encore eu de chance. Merci d'avance!

10
Bharathiraja S

Vous pouvez utiliser le comparateur de groupes et le flux parallèle comme suit:

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

En termes de Java, les comparateurs de tri équivalents ressemblent à ceci:

  1. order by pdate

    Est représenté par

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

    Est représenté par

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

    Est représenté par:

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

Si à tout moment vous devez avoir un ordre décroissant, vous pouvez appeler reversed() sur le comparateur, comme ceci:

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

Notez que la méthode thenComparing est remplacée, offrant la possibilité de transmettre:

  • n comparateur
  • ne fonction - extracteur (fonctionne si la fonction extraite est-a Comparable)
  • ne fonction et un comparateur (car lorsque la valeur extraite n'est pas elle-même un Comparable, vous ne pouvez donc pas utiliser son ordre naturel et devez spécifier comment elle doit être comparée.
13
M. Prokhorov

Au lieu de .sorted() essayez d'utiliser la méthode .sorted(Comparator comparator).

Vous pouvez créer le Comparator utilisé avec .sorted(comparator) en utilisant Comparator.comparing():

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

par exemple:

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

Dans cet exemple, vous pouvez utiliser la référence de méthode Document::getPdate Et Document::getSubject Au lieu de l'expression lambda comme d -> d.getPdate() et d -> d.getSubject()

5
Szymon Stepniak