Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a collection using fluent chaining in Java 8

Given a class.

public class Entity {

    private Long id;
    private String prodName;
    private BigDecimal price;

    // Constructors + getters + setters + hashcode() + equals() + toString().
}

Constructing a list of Entity.

List<Entity> list = new ArrayList<>();

Entity entity = new Entity();
entity.setId(1L);
entity.setProdName("A");
entity.setPrice(new BigDecimal(10));
list.add(entity);

entity = new Entity();
entity.setId(2L);
entity.setProdName("B");
entity.setPrice(new BigDecimal(20));
list.add(entity);

entity = new Entity();
entity.setId(3L);
entity.setProdName("C");
entity.setPrice(new BigDecimal(30));
list.add(entity);

entity = new Entity();
entity.setId(4L);
entity.setProdName("D");
entity.setPrice(new BigDecimal(40));
list.add(entity);

entity = new Entity();
entity.setId(5L);
entity.setProdName("E");
entity.setPrice(new BigDecimal(50));
list.add(entity);

entity = new Entity();
entity.setId(6L);
entity.setProdName("F");
entity.setPrice(new BigDecimal(60));
list.add(entity);

entity = new Entity();
entity.setId(7L);
entity.setProdName("F");
entity.setPrice(new BigDecimal(60));
list.add(entity);

Attempting to sort the list in descending order by price and prodName and then in ascending order by id.

Comparator<Entity> comparator = Comparator.comparing(Entity::getPrice).reversed();
comparator = comparator.thenComparing(Entity::getProdName).reversed();
comparator = comparator.thenComparingLong(Entity::getId);

list = list.stream().sorted(comparator).collect(Collectors.toList());
// Or Collections.sort(list, comparator);
list.stream().forEachOrdered(l -> System.out.println(l.getId() + " : " + l.getPrice() + " : " + l.getProdName()));

After performing sorting, the list should appear like the following.

6 : 60 : F
7 : 60 : F
5 : 50 : E
4 : 40 : D
3 : 30 : C
2 : 20 : B
1 : 10 : A

But the list, after sorting is performed, appears as follows.

1 : 10 : A
2 : 20 : B
3 : 30 : C
4 : 40 : D
5 : 50 : E
6 : 60 : F
7 : 60 : F

The sorted list is not according to the given criteria (descending order by price and prodName and ascending order by id).

What more needs to be done?

like image 793
Tiny Avatar asked Dec 11 '22 20:12

Tiny


1 Answers

You're reversing the whole comparator every time you call reversed(). Instead, just do as your description says:

Comparator<Entity> comparator = Comparator.comparing(Entity::getPrice,
                                                     Comparator.reverseOrder());
comparator = comparator.thenComparing(Entity::getProdName, 
                                      Comparator.reverseOrder());
comparator = comparator.thenComparingLong(Entity::getId);

list = list.stream().sorted(comparator).collect(Collectors.toList());
list.stream().forEachOrdered(l -> System.out.println(l.getId() + " : " + l.getPrice() + " : " + l.getProdName()));
like image 177
JB Nizet Avatar answered Dec 30 '22 00:12

JB Nizet