Menyortir daftar dengan stream.sorted () di Java

96

Saya tertarik untuk menyortir daftar dari aliran. Ini adalah kode yang saya gunakan:

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

Apakah saya melewatkan sesuatu? Daftar tidak diurutkan.

Ini harus mengurutkan daftar sesuai dengan item dengan nilai terendah.

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

Dan metode cetaknya:

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

Jawaban:

147

Ini tidak seperti di Collections.sort()mana referensi parameter diurutkan. Dalam hal ini Anda baru saja mendapatkan aliran yang diurutkan yang perlu Anda kumpulkan dan tetapkan ke variabel lain pada akhirnya:

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

Anda baru saja melewatkan untuk menetapkan hasilnya

Matt
sumber
67

Gunakan list.sortsebagai gantinya:

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

dan membuatnya lebih ringkas dengan menggunakan Comparator.comparing:

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

Setelah salah satu dari ini, listdirinya akan diurutkan.

Masalah Anda adalah yang mengembalikan data yang diurutkan, itu tidak diurutkan seperti yang Anda harapkan.list.stream.sorted

Sungai
sumber
5
list.sort(Comparator.comparing(o -> o.getItem().getValue()));baru bagiku. Bagus!
Neuron
36

Java 8 menyediakan metode api utilitas yang berbeda untuk membantu kami mengurutkan aliran dengan lebih baik.

Jika daftar Anda adalah daftar Integer (atau Double, Long, String dll.,) Maka Anda cukup mengurutkan daftar dengan komparator default yang disediakan oleh java.

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

Membuat komparator dengan cepat:

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

Dengan pembanding default yang disediakan oleh java 8 ketika tidak ada argumen yang diteruskan ke sort ():

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

Jika Anda ingin mengurutkan daftar yang sama dalam urutan terbalik:

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

Jika daftar Anda adalah daftar objek yang ditentukan pengguna, maka:

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

Membuat komparator dengan cepat:

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

Menggunakan metode Comparator.comparingLong () (Kami telah membandingkanDouble (), membandingkanInt () metode juga):

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

Menggunakan metode Comparator.comparing () (metode Generik yang membandingkan berdasarkan metode pengambil yang disediakan):

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

Kita bisa melakukan chaining juga menggunakan metode 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.

Kelas orang

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;
    }
}
Udaya Shankara Gandhi Thalabat
sumber
4
Saya merasa jawaban ini terlalu rinci untuk pertanyaannya, namun tidak menjawab pertanyaan itu sama sekali. Pertimbangkan untuk menggunakan jawaban ini dalam Q / A yang dijawab sendiri.
Sungai
1
Saya juga merasa ini adalah jawaban yang terbaik dan benar. menggunakan Comparator.comparing*adalah cara yang lebih baik dan lebih berorientasi pendekatan
JDK8
0

Tampaknya berfungsi dengan baik:

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

Contoh Input / Output

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

Apakah Anda yakin Anda tidak memverifikasi daftar daripada sortedList[dalam contoh di atas] yaitu Anda menyimpan hasil stream()dalam Listobjek baru dan memverifikasi objek itu?

Tanmay Baid
sumber
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());


    }
}

**** ini berguna untuk mengurutkan objek peta bersarang seperti Map> di sini saya mengurutkan berdasarkan harga objek Item.

Venkat IndianEagle
sumber
0

Ini adalah contoh sederhana:

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

Mungkin saja IDE Anda tidak mendapatkan jdk 1.8 atau versi yang lebih tinggi untuk mengkompilasi kode.

Setel Java versi 1.8 untuk Your_Project > properties> Project Facets> Java version 1.8

Jimmy
sumber