Java Comparator Actual Warfare

1 demand

A project that displays a list of monitored data from an interface, does not require paging, and can be sorted for a long time at present:

Customers want to group [status] first, and then sort [duration].

2 Analysis

Consider the following options:

1. Write js scripts and sort them in groups at the front end.
2. Use Java comparator to sort groups in the back end and render directly in the front end.

After comparison, it is found that using Java comparator is more convenient.

3 Java comparator

There are two implementations of comparators in Java: Comparable (internal comparator) and Comparator (external comparator).

3.1 Comparable interface

Code template:

public class Entity implements Comparable<Entity> {

    @Override
    public int compareTo(Entity o) {
        return 0;
    }
}

Comparable interface supports generic parameters, so one need to compare entity classes only need to implement Comparable interface according to the above code template, and then compare another entity class of the same type.

Because the comparison method is defined in the entity class, it is called an internal comparator.

3.2 Comparator interface

Code template:

public class EntityComparator implements Comparator<Entity> {
    @Override
    public int compare(Entity o1, Entity o2) {
        return 0;
    }
}

The Comparator interface also supports generic parameters. The difference is that it's a comparator class, so it's called an external comparator. Comparator classes are more flexible to use, and we can define multiple comparator classes for different sort scenarios.

4 actual combat

Because business scenarios need to sort the status first, then the length, and the sort can be divided into positive and reverse order, so we use Java external comparator to implement the business logic.

Entity classes to be compared:

public class Record {

    //state
    private String state;

    //Duration
    private String time;

    public Record(String state, String time) {
        this.state = state;
        this.time = time;
    }

    public String getState() {
        return state;
    }

    public String getTime() {
        return time;
    }

    @Override
    public String toString() {
        return "Record{" +
                "state='" + state + '\'' +
                ", time='" + time + '\'' +
                '}';
    }
}

Comparator A: Sort [state] first, and then [length] in positive order.

public class RecordComparator implements Comparator<Record> {
    @Override
    public int compare(Record o1, Record o2) {
        final int stateCompare = o1.getState().compareTo(o2.getState());
        if (stateCompare == 0) {
            return o1.getTime().compareTo(o2.getTime());
        }
        return stateCompare;
    }
}

Comparator B: Sort [state] first, and then sort [length] in reverse order (reverse order).

public class RecordTimeDescComparator implements Comparator<Record> {
    @Override
    public int compare(Record o1, Record o2) {
        final int stateCompare = o1.getState().compareTo(o2.getState());
        if (stateCompare == 0) {
            return o2.getTime().compareTo(o1.getTime());
        }
        return stateCompare;
    }
}

Unit testing:

Record record1 = new Record("In the call", "00:01:08");
Record record2 = new Record("free", "00:18:02");
Record record3 = new Record("In the call", "00:04:04");
Record record4 = new Record("free", "00:01:57");

List<Record> recordList = new ArrayList<>();
recordList.add(record1);
recordList.add(record2);
recordList.add(record3);
recordList.add(record4);

System.out.println("Before sorting:" + recordList);
Collections.sort(recordList, new RecordComparator());
System.out.println("After sorting [in positive chronological order]:" + recordList);

recordList = new ArrayList<>();
recordList.add(record1);
recordList.add(record2);
recordList.add(record3);
recordList.add(record4);

System.out.println("Before sorting:" + recordList);
Collections.sort(recordList, new RecordTimeDescComparator());
System.out.println("After sorting [in reverse chronological order]:" + recordList);

Output results:

Before sorting: [Record{state='In the call', time='00:01:08'}, Record{state='idle', time='00:18:02'}, Record{state='In the call', time='00:04:04'}, Record{state='idle', time='00:01:57'}]
After sorting, [Positive Time Order]: [Record{state='idle', time='00:01:57'}, Record{state='idle', time='00:18:02'}, Record{state='in-call', time='00:01:08'}, Record{state='in-call', time='00:04:04'}]
Before sorting: [Record{state='In the call', time='00:01:08'}, Record{state='idle', time='00:18:02'}, Record{state='In the call', time='00:04:04'}, Record{state='idle', time='00:01:57'}]
After sorting, [time inversion]: [Record{state='idle', time='00:18:02'}, Record{state='idle', time='00:01:57'}, Record{state='in-call', time ='00:04'}, Record{state='in-call', time='00:01:08'}]

The seemingly complex problem can be solved by Java comparator.~

Keywords: Java

Added by wheakory on Fri, 17 May 2019 12:21:55 +0300