110 votes

Tri d'une liste avec stream.sorted () en Java

Je suis intéressé par le tri d'une liste à partir d'un flux. C'est 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 n'est pas en train de trier.

Il convient de 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());
}
 

163voto

Matt Points 3165

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 à une autre variable:

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

Vous avez juste manqué d'assigner le résultat

74voto

River Points 1356

Utiliser list.sort à la place:

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

et de le rendre plus concis en utilisant Comparator.comparing:

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

Après l'un de ces, list lui-même sera triée.

Votre problème, c'est que list.stream.sorted renvoie les données sont triées, il n'a pas de tri en place pendant que vous attendez.

45voto

Java 8 fournit une utilité différente méthodes de l'api pour nous aider à trier les flux mieux.

Si votre liste est une liste de nombres Entiers(ou Double, Long, String, etc.) vous pouvez trier la liste par défaut des comparateurs fournies par java.

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

La création de comparaison sur la mouche:

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

À défaut de comparaison fournis par java 8 quand aucun argument passé à sorted():

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

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

integerList.stream().triés(Comparateur.reverseOrder()).forEach(Système d'.::println); // l'Ordre Inverse

Si votre liste est une liste de défini par l'utilisateur des objets, puis:

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

La création de comparaison sur la mouche:

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

À L'Aide Du Comparateur.comparingLong (), méthode(Nous avons comparingDouble(), comparingInt() les méthodes de trop):

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

À L'Aide Du Comparateur.la comparaison de (), méthode(méthode Générique qui compare basé sur la méthode de lecture fourni):

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

Nous pouvons faire le chaînage aussi l'utilisation de thenComparing() la méthode:

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.

La classe 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;
    }
}

0voto

Tanmay Baid Points 309

Cela semble bien fonctionner:

 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 objet List et que vous vérifiez que objet?

0voto

 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 de carte imbriqués tels que Carte> ici, triés en fonction du prix de l'objet Article.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X