Trier une liste avec stream.sorted () en Java


93

Je suis intéressé par le tri d'une liste à partir d'un flux. Voici le code que j'utilise:

list.stream()
    .sorted((o1, o2)->o1.getItem().getValue().compareTo(o2.getItem().getValue()))
    .collect(Collectors.toList());

Est-ce que je manque quelque chose? La liste ne trie pas.

Il doit trier les listes en fonction de l'élément avec la valeur la plus basse.

for (int i = 0; i < list.size(); i++)
{
   System.out.println("list " + (i+1));
   print(list, i);
}

Et la méthode d'impression:

public static void print(List<List> list, int i)
{
    System.out.println(list.get(i).getItem().getValue());
}

Réponses:


144

Ce n'est pas comme Collections.sort()où la référence de paramètre est triée. Dans ce cas, vous obtenez simplement un flux trié que vous devez collecter et affecter éventuellement à une autre variable:

List result = list.stream().sorted((o1, o2)->o1.getItem().getValue().
                                   compareTo(o2.getItem().getValue())).
                                   collect(Collectors.toList());

Vous venez de manquer d'attribuer le résultat


62

Utilisez à la list.sortplace:

list.sort((o1, o2) -> o1.getItem().getValue().compareTo(o2.getItem().getValue()));

et rendez-le plus succinct en utilisant Comparator.comparing:

list.sort(Comparator.comparing(o -> o.getItem().getValue()));

Après l'un ou l'autre de ces derniers, listlui - même sera trié.

Votre problème est que renvoie les données triées, elles ne sont pas triées comme prévu.list.stream.sorted


5
list.sort(Comparator.comparing(o -> o.getItem().getValue()));était nouveau pour moi. Génial!
Neuron

31

Java 8 fournit différentes méthodes API utilitaires pour nous aider à mieux trier les flux.

Si votre liste est une liste d'entiers (ou Double, Long, Chaîne, etc.), vous pouvez simplement trier la liste avec les comparateurs par défaut fournis par java.

List<Integer> integerList = Arrays.asList(1, 4, 3, 4, 5);

Création d'un comparateur à la volée:

integerList.stream().sorted((i1, i2) -> i1.compareTo(i2)).forEach(System.out::println);

Avec le comparateur par défaut fourni par java 8 quand aucun argument n'est passé à sorted ():

integerList.stream().sorted().forEach(System.out::println); //Natural order

Si vous souhaitez trier la même liste dans l'ordre inverse:

 integerList.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println); // Reverse Order

Si votre liste est une liste d'objets définis par l'utilisateur, alors:

List<Person> personList = Arrays.asList(new Person(1000, "First", 25, 30000),
        new Person(2000, "Second", 30, 45000),
        new Person(3000, "Third", 35, 25000));

Création d'un comparateur à la volée:

personList.stream().sorted((p1, p2) -> ((Long)p1.getPersonId()).compareTo(p2.getPersonId()))
        .forEach(person -> System.out.println(person.getName()));

Utilisation de la méthode Comparator.comparingLong () (Nous avons aussi les méthodes compareDouble (), compareInt ()):

personList.stream().sorted(Comparator.comparingLong(Person::getPersonId)).forEach(person -> System.out.println(person.getName()));

Utilisation de la méthode Comparator.comparing () (méthode générique qui compare en fonction de la méthode getter fournie):

personList.stream().sorted(Comparator.comparing(Person::getPersonId)).forEach(person -> System.out.println(person.getName()));

Nous pouvons également faire du chaînage en utilisant la méthode thenComparing ():

personList.stream().sorted(Comparator.comparing(Person::getPersonId).thenComparing(Person::getAge)).forEach(person -> System.out.println(person.getName())); //Sorting by person id and then by age.

Classe de personne

public class Person {
    private long personId;
    private String name;
    private int age;
    private double salary;

    public long getPersonId() {
        return personId;
    }

    public void setPersonId(long personId) {
        this.personId = personId;
    }

    public Person(long personId, String name, int age, double salary) {
        this.personId = personId;
        this.name = name;
        this.age = age;

        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

4
J'ai l'impression que cette réponse est beaucoup trop détaillée pour la question, mais ne répond pas du tout à la question. Pensez plutôt à utiliser cette réponse dans une Q / R auto-répondue.
Rivière

1
Je pense également que c'est la meilleure et la bonne réponse. l'utilisation Comparator.comparing*est la meilleure approche et plus orientée
JDK8

0

Cela semble fonctionner correctement:

List<BigDecimal> list = Arrays.asList(new BigDecimal("24.455"), new BigDecimal("23.455"), new BigDecimal("28.455"), new BigDecimal("20.455"));
System.out.println("Unsorted list: " + list);
final List<BigDecimal> sortedList = list.stream().sorted((o1, o2) -> o1.compareTo(o2)).collect(Collectors.toList());
System.out.println("Sorted list: " + sortedList);

Exemple d'entrée / sortie

Unsorted list: [24.455, 23.455, 28.455, 20.455]
Sorted list: [20.455, 23.455, 24.455, 28.455]

Êtes-vous sûr de ne pas vérifier la liste au lieu de sortedList[dans l'exemple ci-dessus], c'est-à-dire que vous stockez le résultat de stream()dans un nouvel Listobjet et que vous vérifiez cet objet?


0
Collection<Map<Item, Integer>> itemCollection = basket.values();
Iterator<Map<Item, Integer>> itemIterator =   itemCollection.stream().sorted(new TestComparator()).collect(Collectors.toList()).iterator();



package com.ie.util;

import com.ie.item.Item;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class TestComparator implements Comparator<Map<Item, Integer>> {

// comparator is used to sort the Items based on the price


    @Override
    public int compare(Map<Item, Integer> o1, Map<Item, Integer> o2) {


      //  System.out.println("*** compare method will be called *****");


        Item item1 = null;
        Item item2 = null;


        Set<Item> itemSet1 = o1.keySet();
        Iterator<Item> itemIterator1 = itemSet1.iterator();
        if(itemIterator1.hasNext()){
           item1 =   itemIterator1.next();
        }

        Set<Item> itemSet2 = o2.keySet();
        Iterator<Item> itemIterator2 = itemSet2.iterator();
        if(itemIterator2.hasNext()){
            item2 =   itemIterator2.next();
        }


        return -item1.getPrice().compareTo(item2.getPrice());


    }
}

**** Ceci est utile pour trier les objets cartographiques imbriqués comme Carte> ici, j'ai trié en fonction du prix de l'objet Item.


0

Voici un exemple simple:

List<String> citiesName = Arrays.asList( "Delhi","Mumbai","Chennai","Banglore","Kolkata");
System.out.println("Cities : "+citiesName);
List<String> sortedByName = citiesName.stream()
                .sorted((s1,s2)->s2.compareTo(s1))
                        .collect(Collectors.toList());
System.out.println("Sorted by Name : "+ sortedByName);

Il est possible que votre IDE n'obtienne pas le jdk 1.8 ou la version supérieure pour compiler le code.

Définissez la version Java 1.8 pour Votre_Projet > propriétés> Facettes du projet> Java version 1.8

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.