简体   繁体   中英

Sorting a List of objects by the First element but if Equal sort by the second

I have to sort a list of objects. I have to sort the list by the value time, however, if the time of two or more events is equal, then I have to sort it by its type. All I am looking for is a simple solution, the one I know would not be simple and wouldn't include any already created classes for sorting.

The expected list order

#ID , time, type
5 1.1 Arrived
5 1.1 Scheduled
4 1.2 Arrived
3 4.1 Arrived
2 5.4 Arrived
1 6.0 Arrived
5 61.1 Terminated
4 61.1 Scheduled
4 121.1 Terminated

The list I have:

#ID , time, type
5 1.1 scheduled
5 1.1 arrived
4 1.2 arrived
3 4.1 arrived
2 5.4 arrived
1 6.0 arrived
4 61.1 scheduled
5 61.1 terminated
4 121.1 terminated
3 121.1 scheduled

Have a look at the code to get the things better:

private List<Event> createEventList(List<Process> processList) {
        List<Event> list = new ArrayList<Event>();
        Event event;
        for(Process pr : processList) {
            // arrived
            int id = pr.getID();
            double time = pr.getArrivalTime();
            eventtype type = eventtype.arrived;
            event = new Event(id, time, type);
            list.add(event);

            //terminated
            time = pr.getFinishTime();
            type = eventtype.terminated;
            event = new Event(id,time,type);
            list.add(event);

            //scheduled
            time = pr.getFinishTime()-pr.getBurstTime();
            type = eventtype.scheduled;
            event = new Event(id,time,type);
            list.add(event);

        }
        list = list.stream().sorted(Comparator.comparing(Event::getTime))
                .collect(Collectors.toList());

        return list;

    }

EDIT: Event class and enum

public class Event {

    private int pID = 0;
    private double time = 0.0;
    private eventtype type = null;
    public static enum eventtype{
        arrived,
        scheduled,
        terminated,
    }

    public Event(int pID, double time, eventtype type) {
        super();
        this.pID = pID;
        this.time = time;
        this.type = type;
    }

    @Override
    public String toString() {
        return pID + " " + Math.round(time*10)/10.0 + " " + type.toString();
    }

You can use Comparator#thenComparing to compare by the second object after comparing the first.

list = list.stream().sorted(Comparator.comparing(Event::getTime).thenCompare(Event::getType))
                .collect(Collectors.toList())

You can use thenCompare() to compare second field and no need to use stream() and collect() again since you are assigning result in same list

list.sort(Comparator.comparing(Event::getTime).thenCompare(l ->l.getType().ordinal()));

Since you order by type which is an enum change the order in enum declaration for sort by .ordinal() otherwise you need to define comparator by own.

public static enum eventtype{
    terminated,
    arrived,
    scheduled,
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM