Sắp xếp danh sách với stream.sorted () trong Java


93

Tôi quan tâm đến việc sắp xếp danh sách từ một luồng. Đây là mã tôi đang sử dụng:

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

Tui bỏ lỡ điều gì vậy? Danh sách không sắp xếp.

Nó sẽ sắp xếp danh sách theo mục có giá trị thấp nhất.

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

Và phương pháp in:

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

Câu trả lời:


144

Điều này không giống như Collections.sort()nơi tham chiếu tham số được sắp xếp. Trong trường hợp này, bạn chỉ nhận được một luồng được sắp xếp mà cuối cùng bạn cần thu thập và gán cho một biến khác:

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

Bạn vừa bỏ lỡ chỉ định kết quả


62

Sử dụng list.sortthay thế:

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

và làm cho nó ngắn gọn hơn bằng cách sử dụng Comparator.comparing:

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

Sau một trong hai, listchính nó sẽ được sắp xếp.

Vấn đề của bạn là dữ liệu trả về dữ liệu đã được sắp xếp, nó không được sắp xếp đúng vị trí như bạn mong đợi.list.stream.sorted


5
list.sort(Comparator.comparing(o -> o.getItem().getValue()));là mới đối với tôi. Tuyệt quá!
Neuron

31

Java 8 cung cấp các phương thức api tiện ích khác nhau để giúp chúng tôi sắp xếp các luồng tốt hơn.

Nếu danh sách của bạn là danh sách Số nguyên (hoặc Đôi, Dài, Chuỗi, v.v.) thì bạn có thể chỉ cần sắp xếp danh sách bằng các bộ so sánh mặc định do java cung cấp.

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

Đang tạo bộ so sánh:

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

Với bộ so sánh mặc định được cung cấp bởi java 8 khi không có đối số nào được truyền đến sorted ():

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

Nếu bạn muốn sắp xếp cùng một danh sách theo thứ tự ngược lại:

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

Nếu danh sách của bạn là danh sách các đối tượng do người dùng xác định, thì:

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

Đang tạo bộ so sánh:

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

Sử dụng phương thức Comparator.comparingLong () (Chúng tôi cũng có các phương thức CompareDouble (), CompareInt ()):

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

Sử dụng phương thức Comparator.comparing () (Phương thức chung so sánh dựa trên phương thức getter được cung cấp):

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

Chúng ta cũng có thể thực hiện chuỗi bằng cách sử dụng phương thức 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.

Hạng người

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
Tôi cảm thấy câu trả lời này quá chi tiết cho câu hỏi và chưa giải quyết được câu hỏi. Thay vào đó, hãy cân nhắc sử dụng câu trả lời này trong Câu hỏi / Đáp tự trả lời.
River

1
Tôi cũng cảm thấy rằng đây là câu trả lời đúng và tốt nhất. sử dụng Comparator.comparing*là cách tốt hơn và tiếp cận theo định hướng
JDK8

0

Có vẻ như nó đang hoạt động tốt:

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

Ví dụ đầu vào / đầu ra

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

Bạn có chắc chắn rằng bạn không xác minh danh sách thay vì sortedList[trong ví dụ trên] tức là bạn đang lưu trữ kết quả của stream()một Listđối tượng mới và xác minh đối tượng đó?


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


    }
}

**** điều này rất hữu ích để sắp xếp các đối tượng bản đồ lồng nhau như Bản đồ> ở đây tôi đã sắp xếp dựa trên giá đối tượng Mặt hàng.


0

Đây là một ví dụ đơn giản:

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

Có thể IDE của bạn không nhận được jdk 1.8 hoặc phiên bản cao hơn để biên dịch mã.

Đặt phiên bản Java 1.8 cho Your_Project > thuộc tính> Project Facets> Java phiên bản 1.8

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.