Sortieren einer Liste mit stream.sorted () in Java


93

Ich bin daran interessiert, eine Liste aus einem Stream zu sortieren. Dies ist der Code, den ich verwende:

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

Vermisse ich etwas Die Liste wird nicht sortiert.

Es sollte die Listen nach dem Element mit dem niedrigsten Wert sortieren.

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

Und die Druckmethode:

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

Antworten:


144

Dies ist nicht so, Collections.sort()als würde die Parameterreferenz sortiert. In diesem Fall erhalten Sie nur einen sortierten Stream, den Sie sammeln und eventuell einer anderen Variablen zuweisen müssen:

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

Sie haben es gerade versäumt, das Ergebnis zuzuweisen


62

Verwenden Sie list.sortstattdessen:

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

und machen Sie es prägnanter mit Comparator.comparing:

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

Nach beiden listwird selbst sortiert.

Ihr Problem ist , dass kehrt die sortierten Daten, spielt es keine Art an Ort und Stelle , wie Sie erwarten.list.stream.sorted


5
list.sort(Comparator.comparing(o -> o.getItem().getValue()));war neu für mich. Toll!
Neuron

31

Java 8 bietet verschiedene API-Methoden für Dienstprogramme, mit denen wir die Streams besser sortieren können.

Wenn Ihre Liste eine Liste von Ganzzahlen (oder Double, Long, String usw.) ist, können Sie die Liste einfach mit den von Java bereitgestellten Standardkomparatoren sortieren.

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

Komparator im laufenden Betrieb erstellen:

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

Mit dem von Java 8 bereitgestellten Standardkomparator, wenn kein Argument an sorted () übergeben wurde:

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

Wenn Sie dieselbe Liste in umgekehrter Reihenfolge sortieren möchten:

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

Wenn Ihre Liste eine Liste benutzerdefinierter Objekte ist, dann:

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

Komparator im laufenden Betrieb erstellen:

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

Verwenden der Comparator.comparingLong () -Methode (Wir haben compareDouble (), compareInt () -Methoden auch):

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

Verwenden der Comparator.comparing () -Methode (generische Methode, die anhand der bereitgestellten Getter-Methode vergleicht):

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

Mit der thenComparing () -Methode können wir auch verketten:

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.

Personenklasse

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
Ich bin der Meinung, dass diese Antwort für die Frage viel zu detailliert ist und die Frage dennoch überhaupt nicht anspricht. Verwenden Sie diese Antwort stattdessen in einem selbst beantworteten Q / A.
Fluss

1
Ich denke auch, dass dies die beste und richtige Antwort ist. Verwenden Comparator.comparing*ist der Weg besser und JDK8 orientierter Ansatz
Kakabali

0

Es scheint gut zu funktionieren:

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

Beispiel für Eingabe / Ausgabe

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

Sind Sie sicher, dass Sie keine Liste anstelle von sortedList[im obigen Beispiel] überprüfen, dh Sie speichern das Ergebnis stream()in einem neuen ListObjekt und überprüfen dieses Objekt?


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


    }
}

**** Dies ist hilfreich, um die verschachtelten Kartenobjekte wie Karte zu sortieren.> Hier habe ich nach dem Objektpreis sortiert.


0

Dies ist ein einfaches Beispiel:

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

Möglicherweise erhält Ihre IDE nicht die JDK 1.8- oder höhere Version, um den Code zu kompilieren.

Stellen Sie die Java-Version 1.8 für Your_Project > Eigenschaften> Projektfacetten> Java-Version 1.8 ein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.