Java'da stream.sorted () ile bir listeyi sıralama


96

Bir akıştan bir listeyi sıralamakla ilgileniyorum. Kullandığım kod bu:

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

Bir şey mi kaçırıyorum? Liste sıralanmıyor.

Listeleri en düşük değere sahip maddeye göre sıralaması gerekir.

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

Ve baskı yöntemi:

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

Yanıtlar:


147

Bu, Collections.sort()parametre referansının sıralandığı yer gibi değildir . Bu durumda, sonunda toplamanız ve başka bir değişkene atamanız gereken sıralı bir akış elde edersiniz:

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

Sonucu atamayı kaçırdın


67

list.sortBunun yerine kullanın :

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

ve şunu kullanarak daha özlü hale getirin Comparator.comparing:

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

Bunlardan herhangi birinin ardından listkendisi sıralanacaktır.

Sorununuz, sıralanan verileri döndürmesi , beklediğiniz gibi yerinde sıralanmamasıdır.list.stream.sorted


5
list.sort(Comparator.comparing(o -> o.getItem().getValue()));benim için yeniydi. Harika!
Neuron

36

Java 8, akışları daha iyi sıralamamıza yardımcı olmak için farklı yardımcı program api yöntemleri sağlar.

Listeniz Tamsayılar (veya Double, Long, String vb.) Listesiyse, listeyi java tarafından sağlanan varsayılan karşılaştırıcılarla sıralayabilirsiniz.

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

Anında karşılaştırıcı oluşturma:

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

Sıralı () öğesine hiçbir argüman iletilmediğinde java 8 tarafından sağlanan varsayılan karşılaştırıcı ile:

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

Aynı listeyi tersine sıralamak istiyorsanız:

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

Listeniz kullanıcı tanımlı nesnelerin bir listesiyse, o zaman:

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

Anında karşılaştırıcı oluşturma:

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

Comparator.comparingLong () yöntemini kullanarak (ComparingDouble (), Int () yöntemlerini de karşılaştırıyoruz):

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

Comparator.comparing () yöntemini kullanma (Sağlanan alıcı yöntemine göre karşılaştıran genel yöntem):

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

ThenComparing () yöntemini kullanarak zincirleme de yapabiliriz:

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.

Kişi sınıfı

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
Bu cevabın soru için çok ayrıntılı olduğunu ve yine de soruyu hiç ele almadığını düşünüyorum. Bunun yerine kendi kendine yanıtlanan bir Soru / Cevapta bu yanıtı kullanmayı düşünün.
Nehir

1
Ayrıca bunun en iyi ve doğru cevap olduğunu hissediyorum. kullanmak Comparator.comparing*daha iyi ve daha JDK8 odaklı yaklaşımdır
kakabali

0

İyi çalışıyor gibi görünüyor:

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

Örnek Giriş / Çıkış

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

Listeyi sortedList[yukarıdaki örnekte] yerine doğrulamadığınızdan, yani stream()yeni bir Listnesnenin sonucunu depolayıp bu nesneyi doğruladığınızdan emin misiniz?


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


    }
}

**** Bu, Harita gibi iç içe geçmiş harita nesnelerini sıralamak için yararlıdır> burada Öğe nesne fiyatına göre sıraladım.


0

Bu basit bir örnek:

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

IDE'nizin kodu derlemek için jdk 1.8 veya üst sürümünü almıyor olabilir.

Projeniz > özellikler> Proje Özellikleri> Java sürüm 1.8 için Java sürüm 1.8'i ayarlayın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.