0

I have an ArrayList like this:

ArrayList<Person> list;

The Person type can have a name and a number, both as Strings. I am looking to sort the number strings (not the name) in descending order using the expression below:

Collections.sort(somelist, Collections.reverseOrder());

How can I specify that I want to sort by the number field?

I can get the number by Person.getNumber();

1
  • Do you want to sort the number field (which you say is a string!) numerically or lexically? Commented Mar 17, 2021 at 5:57

2 Answers 2

3

You may need this.

Collections.sort(list, 
            Comparator.comparingInt((Person p) -> Integer.valueOf(p.getNumber())).reversed());

If we need to sort both with other fields, then the following would be helpful.

Collections.sort(list, 
            Comparator.comparingInt((Person p) -> Integer.valueOf(p.getNumber()))
            .thenComparing(p -> p.getName()).reversed());
Sign up to request clarification or add additional context in comments.

2 Comments

This is not a stable sort .. if two people have different names but same number the order can flip around. need to add thenComparing(p.getName())
That right, but the question is only asked for comparing by the number.
0

The example you gave is using the reverse() method, which gives a Comparator<Person> when passed to Collections.sort() in this case is defined to reverse the natural order of a Comparable<Person>. SO your Person class must implement Comparable<Person> - although unfortunately this is not detected at compile timne (but this requirement is described in the javadoc).

So to order by anything (single or multiple fields), you can either implement the Comparable<Person> interface, or something can implement Comparator<Person> - like in this previously asked on SO question Collections.sort with multiple fields.

Generally you should implement a stable comparison (Stable sort - do we really need it?) - i.e. what happens if two objects have the same number but different names - how do they get sorted? If you don't get the same relative position (a before b or b after a) when giving two inputs, but in different orders then it's not stable, and you won't necessarily get the same results each time you sort (if one of the values is a dupe). So here's the old school way of doing the compare method (assuming you can't have null references in your data).

public int compare(final Person a, final Person b) {
  final int comp = a.getNumber().compareTo(b.getNumber());
  if (0 == comp) {
    return a.getName().compareTo(b.getName());
  }
  return comp;
}

And here's a lambda style example including creating a Comparator (HT @Preston) -

Collections.sort(list, 
            Comparator.comparingInt((Person p) -> Integer.valueOf(p.getNumber()))
            .thenComparing(p -> p.getName()).reversed());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.