Ordenar una lista con stream.sorted () en Java

93

Me interesa ordenar una lista de una secuencia. Este es el código que estoy usando:

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

¿Me estoy perdiendo de algo? La lista no se ordena.

Debe ordenar las listas según el elemento con el valor más bajo.

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

Y el método de impresión:

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

Respuestas:

144

Esto no es como Collections.sort()donde se ordena la referencia de parámetro. En este caso, solo obtiene una secuencia ordenada que debe recopilar y asignar a otra variable eventualmente:

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

Te perdiste asignar el resultado

Mate
fuente
62

Utilice en su list.sortlugar:

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

y hazlo más conciso usando Comparator.comparing:

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

Después de cualquiera de estos, listse ordenará.

Su problema es que devuelve los datos ordenados, no se ordenan en su lugar como esperaba.list.stream.sorted

Río
fuente
5
list.sort(Comparator.comparing(o -> o.getItem().getValue()));era nuevo para mi. ¡Excelente!
Neuron
31

Java 8 proporciona diferentes métodos api de utilidad para ayudarnos a ordenar mejor los flujos.

Si su lista es una lista de enteros (o dobles, largos, de cadena, etc.), simplemente puede ordenar la lista con los comparadores predeterminados proporcionados por java.

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

Creando comparador sobre la marcha:

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

Con el comparador predeterminado proporcionado por java 8 cuando no se pasa ningún argumento a sorted ():

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

Si desea ordenar la misma lista en orden inverso:

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

Si su lista es una lista de objetos definidos por el usuario, entonces:

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

Creando comparador sobre la marcha:

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

Usando el método Comparator.comparingLong () (también tenemos métodos comparingDouble (), comparingInt ()):

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

Usando el método Comparator.comparing () (método genérico que compara según el método getter proporcionado):

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

También podemos hacer encadenamiento usando el método 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.

Clase de persona

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
fuente
4
Siento que esta respuesta es demasiado detallada para la pregunta y, sin embargo, no aborda la pregunta en absoluto. En su lugar, considere usar esta respuesta en una Q / A con respuesta propia.
Río
1
También siento que esta es la mejor y correcta respuesta. el uso Comparator.comparing*es el método mejor y más orientado a
JDK8
0

Parece estar funcionando bien:

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

Ejemplo de entrada / salida

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

¿Está seguro de que no está verificando la lista en lugar de sortedList[en el ejemplo anterior], es decir, está almacenando el resultado de stream()en un nuevo Listobjeto y verificando ese objeto?

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


    }
}

**** Esto es útil para ordenar los objetos del mapa anidados como Mapa> aquí los ordené según el precio del objeto del artículo.

Indio VenkatÁguila
fuente
0

Este es un ejemplo simple :

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

Es posible que su IDE no obtenga jdk 1.8 o una versión superior para compilar el código.

Configure la versión 1.8 de Java para Your_Project > propiedades> Facetas del proyecto> Versión 1.8 de Java

Palanqueta
fuente