Here is my attempt at implementing the binary search that must follow:
static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
However, I would like to avoid code duplication and delegate one of the implementations to the other (currently, the first to the second). To do that I need to get rid of the wildcard ?
and use a second generic type like so:
public class BinarySearch {
public static <Q extends Comparable<? super T>, T>
int search(List<Q> xs, T x) {
return search(xs, x, Q::compareTo);
}
public static <T>
int search(List<? extends T> xs, T x, Comparator<? super T> cmp) {
int l = 0, r = xs.size() - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (cmp.compare(xs.get(mid), x) == 0)
return mid;
if (cmp.compare(xs.get(mid), x) < 0)
r = mid - 1;
else
l = mid + 1;
}
return xs.size();
}
}
Unfortunately, this does not compile, failing with the error:
Non-static method cannot be referenced from a static context
How could I fix that?
PS: if you wonder why the signatures from Collections
look the way they do, here is an explanation: How do these two generic signatures for Collections.binarySearch differ?
PPS: there used to be (a now deleted) answer that you cannot pass T::compareTo
in place where a Comparator
is expected. Well, I believe that you can, here is my working implementation of QuickSort that does exactly that: https://github.com/all3fox/algos-java/blob/481f2c71952bf2c7510cb93cc1af8e90016ccf3b/src/main/java/io/github/all3fox/sort/QuickSort.java