Kohei Nozaki's blog 

Array sorting with Java8 idioms


Posted on Sunday Jun 28, 2015 at 04:14PM in Java


Thanks to Java8, now we can write sorting with comparators in very simple idiom. assume we have a JavaBean named Stock as follows:

public class Stock {
    private final String symbol;
    private final LocalDate baseDate;
    private final int price;

    public Stock(String symbol, LocalDate baseDate, int price) {
        this.symbol = symbol;
        this.baseDate = baseDate;
        this.price = price;
    }
...

We have following dataset:

final Stock[] data = {
        new Stock("ORCL", LocalDate.of(2015, 3, 1), 10),
        new Stock("ORCL", LocalDate.of(2015, 3, 2), 11),
        new Stock("ORCL", LocalDate.of(2015, 3, 3), 12),
        new Stock("JAVA", LocalDate.of(2015, 3, 1), 100),
        new Stock("JAVA", LocalDate.of(2015, 3, 2), 110),
        new Stock("JAVA", LocalDate.of(2015, 3, 3), 120),
        new Stock("GOOG", LocalDate.of(2015, 3, 1), 1000),
        new Stock("GOOG", LocalDate.of(2015, 3, 2), 1001),
        new Stock("GOOG", LocalDate.of(2015, 3, 3), 1002),
};

How to get an array that sorted by symbol in ascending order, but baseDate in descending order when they have same symbol? the following code works:

Comparator<Stock> p1 = Comparator.comparing(Stock::getSymbol);
Comparator<Stock> p2 = Comparator.comparing(Stock::getBaseDate).reversed();
Comparator<Stock> p3 = p1.thenComparing(p2);
Arrays.sort(data, p3);

System.out.println(Arrays.toString(data));

The variable p1 stores a Comparator that sorts beans with symbol, and p2 does the same for baseDate but in reversed order, and p3 stores a composit comparator for these two. also you can add more comparators with code like .thenComparing(p4).thenComparing(p5)…​ as well. this yields the following output:

[Stock{symbol='GOOG', baseDate=2015-03-03, price=1002}
, Stock{symbol='GOOG', baseDate=2015-03-02, price=1001}
, Stock{symbol='GOOG', baseDate=2015-03-01, price=1000}
, Stock{symbol='JAVA', baseDate=2015-03-03, price=120}
, Stock{symbol='JAVA', baseDate=2015-03-02, price=110}
, Stock{symbol='JAVA', baseDate=2015-03-01, price=100}
, Stock{symbol='ORCL', baseDate=2015-03-03, price=12}
, Stock{symbol='ORCL', baseDate=2015-03-02, price=11}
, Stock{symbol='ORCL', baseDate=2015-03-01, price=10}
]