Sort Java Collection
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 CustomObject
implements 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.
Sorting a collection of objects
Implement the Comparator interface (once for each different sort order) and use the Collections.sort() method that takes a Comparator as additional parameter.
How to sort a Collection T ?
Collections by themselves do not have a predefined order, therefore you must convert them to
a java.util.List
. Then you can use one form of java.util.Collections.sort
Collection< T > collection = ...;
List< T > list = new ArrayList< T >( collection );
Collections.sort( list );
// or
Collections.sort( list, new Comparator< T >( ){...} );
// list now is sorted
Sort a Java collection object based on one field in it
here is my "1liner":
Collections.sort(agentDtoList, new Comparator<AgentSummaryDTO>(){
public int compare(AgentSummaryDTO o1, AgentSummaryDTO o2){
return o1.getCustomerCount() - o2.getCustomerCount();
}
});
UPDATE for Java 8:
For int datatype
Collections.sort(agentDtoList, (o1, o2) -> o1.getCustomerCount() - o2.getCustomerCount());
or even:
Collections.sort(agentDtoList, Comparator.comparing(AgentSummaryDTO::getCustomerCount));
For String datatype (as in comment)
Collections.sort(list, (o1, o2) -> (o1.getAgentName().compareTo(o2.getAgentName())));
..it expects getter AgentSummaryDTO.getCustomerCount()
Difference between Collections.sort(list) and list.sort(Comparator)
The method List.sort(comparator)
that you are refering to was introduced in Java 8, whereas the utility method Collections.sort
has been there since Java 1.2.
As such, you will find a lot of reference on the Internet mentioning that utility method but that's just because it has been in the JDK for a lot longer.
Note that the change in implementation for Collections.sort
was made in 8u20.
How to use Collections.sort() in Java?
Use this method Collections.sort(List,Comparator) . Implement a Comparator and pass it to Collections.sort().
class RecipeCompare implements Comparator<Recipe> {
@Override
public int compare(Recipe o1, Recipe o2) {
// write comparison logic here like below , it's just a sample
return o1.getID().compareTo(o2.getID());
}
}
Then use the Comparator
as
Collections.sort(recipes,new RecipeCompare());
Collections.sort sorts the wrong list
On this line:
ArrayList<Integer> returnList = list;
you are just creating another reference to the same list (Object) in your sorted
method and any change that you apply to it using this new reference will be reflected in you original reference because they point to the same object. You can do this to create a new list:
private static ArrayList<Integer> sorted(ArrayList<Integer> list){
ArrayList<Integer> returnList = new ArrayList<>(list); // the new keyword creates a new object on the memory heap
Collections.sort(returnList);
return returnList;
}
This time we are creating another ArrayList Object with the elements of you original list. This way the original list won't change when you sort the newer.
This behaviour doesn't apply on Immutable Objects like String or LocalDateTime. These cannot change their state after being created and instead return a new copy with the changes applied.
Java collection sorting
But in the above code, we have no properties in this class. So is possible to sort the above list?
Yes, you could write a Comparator
that orders based on hash code (hashCode()
) or string value (toString()
), and use that to sort the list ...
Collections.sort(l, new MyComparator()).
But it is unclear would be gained by that, as the resulting orders have no particular meaning. Indeed, if you are free to choose whatever basis you wish for sorting, then why not sort the list elements by their index in the list? Then your list is always trivially sorted without invoking any methods.
Why is Collections.sort() much slower than Arrays.sort()?
So, there are two different methods with totally different algorithms here:
Arrays.sort(int[])
uses a dual-pivot quicksort algorithm.
Collections.sort(List<T>)
calls list.sort(null)
which in turn calls Arrays.sort(T[])
. This uses a Timsort algorithm.
So, let's compare Arrays.sort(int[])
and Arrays.sort(T[])
.
T[]
is a boxed array so there is one extra level of indirection: for each call, you have to unwrap Integer. This certainly leads to an overhead. On the other hand,int[]
is a primitive array so all elements are available "immediately".- TimSort is a variation of a classic mergesort algorithm. It is faster than mergesort but it still slower than quicksort because
- quicksort has fewer data movements on random data
- quicksort requires
O(log(n))
extra space while TimSort requiresO(n)
to provide stability which also leads to an overhead.
Related Topics
Explicitly Calling a Default Method in Java
How to Add Javafx Runtime to Eclipse in Java 11
When Is the @JSONproperty Property Used and What Is It Used For
Difference Between Java Hh:Mm and Hh:Mm on Simpledateformat
How to Count Occurrences with Groupby
Simpledateformat Parsing Date with 'Z' Literal
How to Convert Milliseconds to "Hh:Mm:Ss" Format
Java - Class.Getresource Returns Null
How to Call a Static Method in Jsp/El
Selenium Webdriver How to Resolve Stale Element Reference Exception
Cannot Parse String in Iso 8601 Format, Lacking Colon in Offset, to Java 8 Date
Build Eclipse Java Project from Command Line
Error: Selection Does Not Contain a Main Type
How to Store Date/Time and Timestamps in Utc Time Zone with JPA and Hibernate