Reputation: 604
What is the difference between Collections.sort(list)
and Collections.sort(list,null)
I supposed both of them compared elements in the list in their natural order.
So I tried these two codes:
CODE 1:
List<Object> list=Arrays.asList("hello",123);
Collections.sort(list);
CODE 2:
List<Object> list=Arrays.asList("hello",123);
Collections.sort(list,null);
The latter compiles but former doesn't giving the expected compiler error that instances of class Object are not comparable. Why latter does not give compile time error.
EDIT: Based on the comment given below. I understand why latter doesn't give compile time error but on running it throws ClassCastException : String cannot be converted into Integer
. How it deduced that runtime objects are String and Integer because what I think
public static sort(List<Object> list) ---> Since list was of type object
{
// For instances of object in list call the compareTo method
}
}
Upvotes: 0
Views: 1310
Reputation: 63955
Java's generic types are checked at compile time. If you violate the constraits, you can't even compile. The first method is defined as:
<T extends Comparable<? super T>> void sort(List<T> list)
That requires that the List
you use is of a type that extend Comparable
, specifically some Comparable<X>
where X may be any superclass of T. Sounds complicated but doesn't even matter here (try understanding http://yzaslavs.blogspot.de/2010/07/generics-pecs-principle-step-by-step.html if you're interested in that part). List<Object>
does not match the first part already. Object
doesn't implement any Comparable
. => Compiler says no.
The second one is defined as
<T> void sort(List<T> list, Comparator<? super T> c)
that no longer requires that the type of the List
has any special property. Any T will work. The only requirement is that you can provide an implementation of Comparator
that is able to sort T or a super type. null
is like a joker and fits anything. The compiler will not complain even if using null is probably wrong. You do see the problem at runtime.
The reason for
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at java.lang.Integer.compareTo(Integer.java:52)
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
at java.util.Arrays.sort(Arrays.java:537)
at java.util.TimSort.sort(TimSort.java:178)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
at Main.main(Main.java:9)
is that at "TimSort.java:178" it does
static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c) {
if (c == null) {
Arrays.sort(a, lo, hi);
return;
}
which falls back to natural sorting like your first call would do. However it's just a Object[]
array at that point and nothing can guarantee that types are actually comparable. It simply casts the types and that fails depending on your luck & content of the list either in Integer.compareTo( ) or String.compareTo( ) because those methods require their own type.
Upvotes: 2
Reputation: 195079
These are two different methods in Collections
//here the elements in list should impl. Comparable
Collections.sort(list)
//here we need a Comparator object, (null is Comparator obj too)
Collections.sort(list, null)
Now comes to the question of runtime classcast problem.
Java converts your list into array to do the sort in background. If your Comparator
is null, java will cast the element to Comparable
to do sort. Fortunately, the two elements in your list both (String and Integer
) implemented Comparable
. so till here no Exception.
You have only two elements (2<7 7 is the insertionsort threshold) in your list, so java just simply do insertion sort. Take the Integer, and call the compareTo()
method with your string as parameter. Here java cast the parameter to Integer, so that it can compare. As you've seen, String
cannot be cast to Integer
, you got that Exception.
Upvotes: 1
Reputation: 41200
> what is null?
According to JSL -
There is also a special null type, the type of the expression null, which has no name. Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type. The null reference is the only possible value of an expression of null type. The null reference can always be cast to any reference type. In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.
As null
can be reference of any type so it can be reference of Comparator
as well, That is why compiler accepts Collections.sort(list,null);
.
Where as Collections.sort(list,new Object());
gives compile time exception.
At the time of comparison check compareTo
Method will be called Where in Integer.compareTo
method it generate ClassCastException
.
Upvotes: 0
Reputation: 81
There is no difference between these two, Is clearly mentioned in api doc. Refer Collections
Upvotes: 0