85

I have a Java collection:

Collection<CustomObject> list = new ArrayList<CustomObject>();

CustomObject has an id field now before display list I want to sort this collection by that id.

Is there any way I could that do that?

falsarella
  • 12,217
  • 9
  • 69
  • 115
Makky
  • 17,117
  • 17
  • 63
  • 86
  • Possible duplicate of [How to sort a Collection?](https://stackoverflow.com/questions/2477261/how-to-sort-a-collectiont) – Hamdi Jul 29 '17 at 15:53

15 Answers15

167

Use a Comparator:

List<CustomObject> list = new ArrayList<CustomObject>();
Comparator<CustomObject> comparator = new Comparator<CustomObject>() {
    @Override
    public int compare(CustomObject left, CustomObject right) {
        return left.getId() - right.getId(); // use your logic
    }
};

Collections.sort(list, comparator); // use the comparator as much as u want
System.out.println(list);

Additionally, if CustomObjectimplements Comparable, then just use Collections.sort(list)

With JDK 8 the syntax is much simpler.

List<CustomObject> list = getCustomObjectList();
Collections.sort(list, (left, right) -> left.getId() - right.getId());
System.out.println(list);

Much simplier

List<CustomObject> list = getCustomObjectList();
list.sort((left, right) -> left.getId() - right.getId());
System.out.println(list);

Simplest

List<CustomObject> list = getCustomObjectList();
list.sort(Comparator.comparing(CustomObject::getId));
System.out.println(list);

Obviously the initial code can be used for JDK 8 too.

Kowser
  • 8,123
  • 7
  • 40
  • 63
  • What if they want to sort more than one time? – Hunter McMillen Aug 05 '11 at 14:21
  • Edited the answer, please check. Obviously its not a big deal if it is understandable how to use the comparator. If you can do it one time, it can be done n times also :) – Kowser Aug 05 '11 at 14:28
  • Aye ... if class implement comparable then dont need to pass comparator ...nice ..ta – Makky Aug 05 '11 at 14:28
  • Who gave the down vote, can you enlighten me? please? May be I can learn something better. – Kowser Aug 05 '11 at 14:31
  • 6
    The method sort(List, Comparator super T>) in the type Collections is not applicable for the arguments (Collection, Comparator) you cannot pass a Collection to sort method which is dead annoying – gibffe Nov 01 '12 at 10:53
  • 5
    The sort method works for Lists, not Collections. The type of the list variable should be changed to List for this example to work. – Eric Vasilik Nov 14 '12 at 10:39
  • Comparison by subtraction should be avoided, please see [Java Integer compareTo() - why use comparison vs. subtraction?](https://stackoverflow.com/questions/2728793/java-integer-compareto-why-use-comparison-vs-subtraction) – mightyWOZ Nov 19 '21 at 15:32
36

The question is: "Sort Collection". So you can't use Collections.sort(List<T> l, Comparator<? super T> comparator).

Some tips:

For Collection type:

Comparator<String> defaultComparator = new Comparator<String>() {
   @Override
   public int compare(String o1, String o2) {
       return o1.compareTo(o2);
   }
};

Collection<String> collection = getSomeStringCollection();
String[] strings = collection.toArray(new String[collection.size()]);
Arrays.sort(strings, defaultComparator);
List<String> sortedStrings = Arrays.asList(strings);

Collection<String> collection = getSomeStringCollection();
List<String> list = new ArrayList(collection);
Collections.sort(list, defaultComparator);
collection = list; // if you wish

For List type:

List<String> list = getSomeStringList();
Collections.sort(list, defaultComparator);

For Set type:

Set<String> set = getSomeStringSet();
// Than steps like in 'For Collection type' section or use java.util.TreeSet
// TreeSet sample:
// Sorted using java.lang.Comparable.
Set<String> naturalSorted = new TreeSet(set);

Set<String> set = getSomeStringSet();
Set<String> sortedSet = new TreeSet(defaultComparator);
sortedSet.addAll(set);

Java 8 version. There is java.util.List#sort(Comparator<? super E> c) method

List<String> list = getSomeStringList();
list.sort(defaultComparator);

or

List<String> list = getSomeStringList();
list.sort((String o1, String o2) -> o1.compareTo(o2));

or for types that implements Comparable:

List<String> list = getSomeStringList();
list.sort(String::compareTo);
Aliaksei Yatsau
  • 749
  • 7
  • 12
12

A slightly different example say if you have a class that doesn't implement Comparable but you still want to sort it on a field or method.

Collections.sort(allMatching, new Comparator<ClassOne>() {
  @Override public int compare(final ClassOne o1, final ClassOne o2) {
    if (o1.getMethodToSort() > o2.getMethodToSort()) {
      return 1;
    } else if (o1.getMethodToSort() < o2.getMethodToSort()) {
      return -1;
    }  
    return 0;
  }
});
Shawn Vader
  • 12,285
  • 11
  • 52
  • 61
  • The if statement you implemented does exactly what `compareTo()` does already. – Hunter McMillen Aug 05 '11 at 14:33
  • The difference is that in this example the class ClassOne is not a comparable class, it doesn't implement Comparable. I was just trying to show an example of how you can use a collection and a comparator to sort non comparable objects. ClassOne has no compareTo method.. – Shawn Vader Aug 05 '11 at 15:18
  • doesnt work with java 6 (Collections.sort limited to List) – phil294 Feb 22 '16 at 13:44
  • You won't find a Collections.sort taking a Set in Java 7 or 8. By definition a List is an ordered sequence of elements whereas Set is a distinct list of elements which is unordered. If you want ordering in a Set look at TreeSet – Shawn Vader Feb 22 '16 at 21:54
8

You should implement the Comparator interface.

example:

public class CustomComparator implements Comparator<CustomObject> 
{
    @Override
    public int compare(CustomObject o1, CustomObject o2) {
        return o1.getId().compareTo(o2.getId());
    }
}

Then you can use the Collections classes Collections.sort() method:

Collections.sort(list, new CustomComparator());
Qwerky
  • 18,217
  • 6
  • 44
  • 80
Hunter McMillen
  • 59,865
  • 24
  • 119
  • 170
5

As of Java 8 you now can do it with a stream using a lambda:

list.stream().sorted(Comparator.comparing(customObject::getId))
             .foreach(object -> System.out.println(object));
JNYRanger
  • 6,829
  • 12
  • 53
  • 81
GerSui
  • 71
  • 2
  • 3
5

A lot of correct answers, but I haven't found this one: Collections cannot be sorted, you can only iterate through them.

Now you can iterate over them and create a new sorted something. Follow the answers here for that.

estani
  • 24,254
  • 2
  • 93
  • 76
5

Implement the Comparable interface on your customObject.

DwB
  • 37,124
  • 11
  • 56
  • 82
4

Comparator is the way

Also See

Community
  • 1
  • 1
jmj
  • 237,923
  • 42
  • 401
  • 438
2

Use sort.

You just have to do this:

All elements in the list must implement the Comparable interface.

(Or use the version below it, as others already said.)

zw324
  • 26,764
  • 16
  • 85
  • 118
1

With Java 8 you have several options, combining method references and the built-in comparing comparator:

import static java.util.Comparator.comparing;

Collection<CustomObject> list = new ArrayList<CustomObject>();

Collections.sort(list, comparing(CustomObject::getId));
//or
list.sort(comparing(CustomObject::getId));
assylias
  • 321,522
  • 82
  • 660
  • 783
0

You can use java Custom Class for the purpose of sorting.

0

SortedSet and Comparator. Comparator should honour the id field.

Aravind Yarram
  • 78,777
  • 46
  • 231
  • 327
  • @Qwerky - I know he has a list. I am suggesting him to use a Set. Unless he wants to maintain duplicates and insertion order. – Aravind Yarram Aug 05 '11 at 15:04
0

Your example:

Collection<CustomObject> list = new ArrayList<CustomObject>();

You can also use a comparator:

list.sort(Comparator.comparingLong(CustomObject::getSomethingToCompare));

Just replace the comparingLong method, there are quite a few options, but it depends on what you want to pass on the "getSomethingToCompare".

This link may help too.

YanMax
  • 75
  • 4
-1

You can also use:

Collections.sort(list, new Comparator<CustomObject>() {
    public int compare(CustomObject obj1, CustomObject obj2) {
        return obj1.id - obj2.id;
    }
});
System.out.println(list);
Micho
  • 3,929
  • 13
  • 37
  • 40
Shrikant
  • 11
  • 1
-3

To be super clear, Collection.sort(list, compartor) does not return anything so something like this list = Collection.sort(list, compartor); will throw an error (void cannot be converted to [list type]) and should instead be Collection.sort(list, compartor)