Sort Java Collection

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 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.

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[]).

  1. 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".
  2. 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 requires O(n) to provide stability which also leads to an overhead.


Related Topics



Leave a reply



Submit