问题
So I am searching a huge ArrayList for a particular String value, but I need Collections.binarySearch() to return a value >=0 if the String I am looking for is equal( non case-sensitive) to the String I pass into the binarySearch() method.
Now in the source code for Collections.binarySearch(), it eventually calls the following lines of code.
Comparable<? super T> midVal = list.get(mid);
int cmp = midVal.compareTo(key);
So seen as I cannot override String as its final (therefore preventing me from overriding its compareTo() method to call compareToIgnoreCase() ), is there any other I can achieve this?
Any help would be great thanks.
回答1:
To perform case-insensitive binary search, use String::compareToIgnoreCase
as a comparator:
int i = Collections.binarySearch(list, key, String::compareToIgnoreCase);
This will perform faster than comparing two strings reduced to the same case, because compareToIgnoreCase()
compares chars one by one, reducing case of chars only if needed, which allows to return fast if strings are different in first chars.
NB: To make binarySearch()
with this comparator work properly, collection must be sorted using exactly the same comparator:
Collections.sort(list, String::compareToIgnoreCase);
回答2:
Use an external Comparator, because java.util.Collections
has a binarySearch
method with this signature:
public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
Your comparator would look something like
public class CaseInsensitiveComparator implements Comparator<String> {
public int compare(String s1, String s2) {
// check if any of the arguments are null, otherwise
return s1.toLowerCase().compareTo(s2.toLowerCase());
}
}
Even if you could extend String to override the compareTo
method, I do not think that would be a good idea.
来源:https://stackoverflow.com/questions/30191696/making-collections-binarysearch-work-with-comparetoignorecase