การเรียงลำดับรายการด้วย stream.sorted () ใน Java


96

ฉันสนใจจัดเรียงรายการจากสตรีม นี่คือรหัสที่ฉันใช้:

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

ฉันพลาดอะไรไปรึเปล่า? รายการไม่ได้เรียงลำดับ

ควรจัดเรียงรายการตามรายการที่มีค่าต่ำสุด

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

และวิธีการพิมพ์:

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

คำตอบ:


147

ซึ่งไม่เหมือนกับCollections.sort()ตำแหน่งที่การอ้างอิงพารามิเตอร์ถูกจัดเรียง ในกรณีนี้คุณจะได้รับสตรีมแบบเรียงลำดับที่คุณต้องรวบรวมและกำหนดให้กับตัวแปรอื่นในที่สุด:

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

คุณพลาดที่จะกำหนดผลลัพธ์


67

ใช้list.sortแทน:

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

และทำให้กระชับมากขึ้นโดยใช้Comparator.comparing:

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

หลังจากอย่างใดอย่างหนึ่งแล้วlistตัวมันเองจะถูกจัดเรียง

ปัญหาของคุณคือ ส่งคืนข้อมูลที่เรียงลำดับข้อมูลไม่ได้เรียงตามที่คุณคาดหวังlist.stream.sorted


5
list.sort(Comparator.comparing(o -> o.getItem().getValue()));เป็นเรื่องใหม่สำหรับฉัน เยี่ยมมาก!
Neuron

36

Java 8 มีวิธีการ API ยูทิลิตี้ที่แตกต่างกันเพื่อช่วยให้เราเรียงลำดับสตรีมได้ดีขึ้น

หากรายการของคุณเป็นรายการจำนวนเต็ม (หรือ Double, Long, String เป็นต้น) คุณสามารถจัดเรียงรายการด้วยตัวเปรียบเทียบเริ่มต้นที่จัดทำโดย java

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

การสร้างตัวเปรียบเทียบแบบทันที:

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

ด้วยตัวเปรียบเทียบเริ่มต้นที่จัดเตรียมโดย java 8 เมื่อไม่มีอาร์กิวเมนต์ส่งไปยัง sorted ():

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

หากคุณต้องการจัดเรียงรายการเดียวกันในลำดับย้อนกลับ:

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

หากรายการของคุณเป็นรายการของวัตถุที่ผู้ใช้กำหนดให้:

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

การสร้างตัวเปรียบเทียบแบบทันที:

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

ใช้วิธี Comparator.comparingLong () (เรามีการเปรียบเทียบ Double (), CompareInt () วิธีการด้วย):

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

การใช้ Comparator.comparing () method (Generic method ซึ่งเปรียบเทียบตามวิธี getter ที่ให้มา):

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

เราสามารถทำโซ่ได้เช่นกันโดยใช้เมธอด 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.

ระดับบุคคล

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
ฉันรู้สึกว่าคำตอบนี้มีรายละเอียดมากเกินไปสำหรับคำถามและยังไม่ได้ตอบคำถามเลย ลองใช้คำตอบนี้ใน Q / A ที่ตอบด้วยตนเองแทน
แม่น้ำ

1
ฉันยังรู้สึกว่านี่เป็นคำตอบที่ดีที่สุดและถูกต้อง การใช้Comparator.comparing*เป็นวิธีที่ดีกว่าและมุ่งเน้น JDK8 มากขึ้น
kakabali

0

ดูเหมือนว่าจะทำงานได้ดี:

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

ตัวอย่างอินพุต / เอาต์พุต

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

คุณแน่ใจหรือไม่ว่าคุณไม่ได้ยืนยันรายการแทนที่จะเป็นsortedList[ในตัวอย่างด้านบน] นั่นคือคุณกำลังจัดเก็บผลลัพธ์ของวัตถุstream()ใหม่Listและยืนยันวัตถุนั้น


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


    }
}

**** สิ่งนี้มีประโยชน์ในการจัดเรียงวัตถุในแผนที่ที่ซ้อนกันเช่นแผนที่> ที่นี่ฉันจัดเรียงตามราคาวัตถุสิ่งของ


0

นี่เป็นตัวอย่างง่ายๆ:

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 ของคุณไม่ได้รับ jdk 1.8 หรือเวอร์ชันบนเพื่อคอมไพล์โค้ด

ตั้งค่า Java เวอร์ชัน 1.8 สำหรับ Your_Project > คุณสมบัติ> Project Facets> Java เวอร์ชัน 1.8

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.