クラスの複数のフィールドでソートする

# 概要

クラスの複数のフィールドでソートをするサンプルプログラムです。

## サンプルコード

```java
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.time.FastDateFormat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Sample {

    public static void main(String ... args) throws Exception {
        FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd");

        /** サンプルデータ */
        List<Data> sampleList = new ArrayList<>();
        sampleList.add(new Data(1L,"CCC", fdf.parse("2017-02-26")));
        sampleList.add(new Data(1L,"BBB", fdf.parse("2017-02-27")));
        sampleList.add(new Data(1L,"KKK", fdf.parse("2017-02-28")));
        sampleList.add(new Data(2L,"AAA", fdf.parse("2017-02-25")));
        sampleList.add(new Data(2L,"DDD", fdf.parse("2017-02-24")));
        sampleList.add(new Data(2L,"QQQ", fdf.parse("2017-02-23")));
        sampleList.add(new Data(3L,"EEE", fdf.parse("2017-02-22")));
        sampleList.add(new Data(3L,"FFF", fdf.parse("2017-02-20")));
        sampleList.add(new Data(3L,"OOO", fdf.parse("2017-02-21")));

        //ソートさせたいフィールドをカンマ区切りで指定します。
        //フィールド名の先頭に-を付けると反転させます。
        List<Data> result = sampleList.stream()
                .sorted(Data.compare("id,-updated"))
                .collect(Collectors.toList());

        result.forEach(data -> System.out.println(ToStringBuilder.reflectionToString(data)));
        // 実行結果
        // [id=1,name=KKK,updated=Tue Feb 28 00:00:00 JST 2017]
        // [id=1,name=BBB,updated=Mon Feb 27 00:00:00 JST 2017]
        // [id=1,name=CCC,updated=Sun Feb 26 00:00:00 JST 2017]
        // [id=2,name=AAA,updated=Sat Feb 25 00:00:00 JST 2017]
        // [id=2,name=DDD,updated=Fri Feb 24 00:00:00 JST 2017]
        // [id=2,name=QQQ,updated=Thu Feb 23 00:00:00 JST 2017]
        // [id=3,name=EEE,updated=Wed Feb 22 00:00:00 JST 2017]
        // [id=3,name=OOO,updated=Tue Feb 21 00:00:00 JST 2017]
        // [id=3,name=FFF,updated=Mon Feb 20 00:00:00 JST 2017]

    }

    private static class Data {
        private static Comparator<Data> ID_COMP = Comparator.comparing(Data::getId);
        private static Comparator<Data> NAME_COMP = Comparator.comparing(Data::getName);
        private static Comparator<Data> UPDATED_COMP = Comparator.comparing(Data::getUpdated);
        private static Map<String, Comparator<Data>> SORT_FIELD = new HashMap<>();
        static {
            SORT_FIELD.put("id", ID_COMP);
            SORT_FIELD.put("-id", ID_COMP.reversed());
            SORT_FIELD.put("name", NAME_COMP);
            SORT_FIELD.put("-name", NAME_COMP.reversed());
            SORT_FIELD.put("updated", UPDATED_COMP);
            SORT_FIELD.put("-updated", UPDATED_COMP.reversed());
        }

        public static Comparator<Data> compare(String sortFields) {
            return Arrays.stream(sortFields.split(","))
                    .map(field -> Data.SORT_FIELD.get(field))
                    .reduce(Comparator::thenComparing)
                    .get();
        }

        private Long id;
        private String name;
        private Date updated;

        public Data(Long id, String name, Date updated) {
            this.id = id;
            this.name = name;
            this.updated = updated;
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Date getUpdated() {
            return updated;
        }

        public void setUpdated(Date updated) {
            this.updated = updated;
        }
    }
}
```