Romi
Romi

Reputation: 4921

How to perform a series of sort operation on arraylist (multiple sort criteria)

I have an arrayList of objects and I want to run a series of sort operations on this list. I would want to sort them by first by name, and if two names are same than sort them by id, for example.

How can i implement it?

This is my code

Comparator<Ticket> mc;
mc = new TicketIdComparator();
Collections.sort(tickets, mc);


final class TicketIdComparator implements Comparator<Ticket>

{

    @Override
    public int compare(Ticket ticket1, Ticket ticket2) {
        String TicketId1 = ((Ticket) ticket1).getNumber();
        String TickedId2 = ((Ticket) ticket2).getNumber();

        int num1=Integer.parseInt(TicketId1);
        int num2 =Integer.parseInt(TickedId2);

        if (num1<num2)
            return 1;
        if (num1>num2)
            return -1;
        return 0;



    }
}

This code sorting list by id, but again i want to sort on name

Upvotes: 3

Views: 1766

Answers (6)

Christophe Roussy
Christophe Roussy

Reputation: 16999

With Java 8 you can use lambdas and based on answer by Peter Lawrey you can do something pretty:

        Collections.sort(users, comparatorFrom(

                    (final User u1, final User u2) -> u1.getDomain().getFirstName()
                        .compareTo(u2.getFirstName()),

                    (final User u1, final User u2) -> u1.getLastName().compareTo(u2.getLastName()),

                    ...more comparators here...

               ));

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533472

You can write a Comparator from a collection of comparators.

public static <T extends Comparable<T>> Comparator<T> comparatorFrom(final Comparator<T>... comparators) {
    return new Comparator<T>() {
        @Override
        public int compare(T o1, T o2) {
            for (Comparator<T> comparator : comparators) {
                final int cmp = comparator.compare(o1, o2);
                if (cmp != 0) return cmp;
            }
            return 0;
        }
    };
}

// you can then use
Arrays.sort(list, comparatorFrom(comp1, comp2, comp3, comp4));

Upvotes: 5

varsha
varsha

Reputation: 314

Collections.sort(myList, new Comparator() {

 @Override
 public int compare(Object o1, Object o2)
 {
    // write your ordering code here for sorting list by id
    return 0;
 }

});

list with sorted by id

Collections.sort(myList, new Comparator() {

 @Override
 public int compare(Object o1, Object o2)
 {
    // write your ordering code here for sorting list by name
    return 0;
 }

});

it will give list with sorted by name

Upvotes: 1

Luciano
Luciano

Reputation: 8582

As you said, and similar as the code you already wrote you would create a class that implements the Comparator interface for Ticket. First, you compare the ticket's names using a String comparator, and if that results in 0 (equal name) then you would compare by id in the same comparator.

Make sure the string comparator does trimming before (remove before and after empty spaces) and maybe ignore casing, that's up to you.

If you want some kind of generalization, then you can write a decorator comparator which calls the more specifics ones. If you want to know more about this, let me know.

Upvotes: 2

Jordan Bentley
Jordan Bentley

Reputation: 1309

  Collections.sort(myList, new Comparator() {

     @Override
     public int compare(Object o1, Object o2)
     {
        // write your ordering code here
        return 0;
     }

  });

Just fill in the code for the comparison you want and Java will handle the sorting for you.

Edit for updated question:

Comparator<Ticket> mc;
mc = new TicketIdComparator();
Collections.sort(tickets, mc);


final class TicketIdComparator implements Comparator<Ticket>

{

    @Override
    public int compare(Ticket ticket1, Ticket ticket2) {
        String TicketId1 = ((Ticket) ticket1).getNumber();
        String TickedId2 = ((Ticket) ticket2).getNumber();

        int num1=Integer.parseInt(TicketId1);
        int num2 =Integer.parseInt(TickedId2);

        if (num1<num2)
            return 1;
        else if (num1>num2)
            return -1;
        else
            return ticket1.getName().compare(ticket2.getName());
    }
}

Upvotes: 3

okrumnow
okrumnow

Reputation: 2416

You need to use a stable sorting algorithm, then sort by ID first and after that sort by name.

Check out this comparison of algorithms to find one that suits your needs.

Upvotes: 0

Related Questions