Why are there non generic versions of binary search in Java?
Is it because they don't want to crash existing implementations?
Why are there non generic versions of binary search in Java?
Is it because they don't want to crash existing implementations?
There is of course a generic version of binarySearch
1.
The reason why there are non-generic overloads is performance: value types would need to be boxed (and thus copied) in order to be able to use a generic binarySearch
. Same goes for sort
and other algorithms.
1 In fact there’s more than one generic overload but that’s not relevant here.
It is unclear what "non generic versions of binary search" you are talking about.
If you are talking about the versions of binarySearch
that take arrays of primitive types, it's because generics only apply to reference types, so a generic binary search method could not possibly handle arrays of primitive types.
If you are talking about the versions of binarySearch
that take Object[]
:
public static int binarySearch(Object[] a, Object key)
public static int binarySearch(Object[] a, int fromIndex, int toIndex, Object key)
How would they make it generic?
Option 1: public static <T> int binarySearch(T[] a, T key)
In this case, there is no benefit to making it generic.
The following two method signatures would be equivalent -- any set of arguments that you can pass to one, you can pass to the other:
public static int binarySearch(Object[] a, Object key)
public static <T> int binarySearch(T[] a, T key)
This is because 1) T
can be chosen to be Object
, so the generic version includes the non-generic version; and 2) any reference array type is a subtype of Object[]
, and any reference type is a subtype of Object
, so the non-generic version includes the generic version.
Since they are equivalent, and thus the T
is useless, the simpler version (without the generic type parameter) is better.
Option 2: they could have made it
public static <T extends Object & Comparable<? super T>>
int binarySearch(T[] a, T key)
but this would break compatibility with old code depending on it taking Object[]
and Object
(without any constraint on it being a type that is comparable to itself). APIs that take previously non-generic classes that now take a parameterized type do not break compatibility, because old code would still work with raw types. However, in this case, raw types do not help because arrays are reified both before and after generics.