[JAVA] Sort by multiple fields in the class

Overview

This is a sample program that sorts by multiple fields in the class.

Sample code

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

        /**Sample data*/
        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")));

        //Specify the fields you want to sort, separated by commas.
        //At the beginning of the field name-If is added, it will be inverted.
        List<Data> result = sampleList.stream()
                .sorted(Data.compare("id,-updated"))
                .collect(Collectors.toList());

        result.forEach(data -> System.out.println(ToStringBuilder.reflectionToString(data)));
        //Execution result
        // [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;
        }
    }
}

Recommended Posts

Sort by multiple fields in the class
Specify multiple sort conditions in Swift
I checked the package name referenced by the class contained in the JAR file
[Java] Sort by multiple keys while considering null
When you get lost in the class name
Class in Ruby
Call a method of the parent class by explicitly specifying the name in Ruby
Implement the algorithm in Ruby: Day 2 -Bubble sort-
Specify multiple sort conditions in Swift
Get multiple Resources that match the pattern in spring
Format of the log output by Tomcat itself in Tomcat 8
Read the packet capture obtained by tcpdump in Java
Return the execution result of Service class in ServiceResponse class
Get the name of the test case in the JUnit test class
Include the source code generated by Doma in the source JAR
A note for Initializing Fields in the Java tutorial
[Ruby / Rails] Set a unique (unique) value in the class
Summarize the additional elements of the Optional class in Java 9
[java] sort in list
About the StringBuilder class
How to use the same Mapper class in multiple data sources with Spring Boot + MyBatis
NullpointException in injecting class
How to get the class name / method name running in Java
Install by specifying the version of Django in the Docker environment
How to connect the strings in the List separated by commas
Determine that the value is a multiple of 〇 in Ruby
When using the constructor of Java's Date class, the date advances by 1900.
Find out all timezone IDs supported by the Java TimeZone class