使Collections.binarySearch()与compareToIgnoreCase一起使用?

时间:2015-05-12 13:01:04

标签: java string collections binary-search

所以我在一个巨大的ArrayList中搜索特定的String值,但如果我要查找的String与String相等(非区分大小写),我需要Collections.binarySearch()返回值> = 0我传入binarySearch()方法。

现在在Collections.binarySearch()的源代码中,它最终会调用以下代码行。

 Comparable<? super T> midVal = list.get(mid);
 int cmp = midVal.compareTo(key);

因为我无法覆盖String作为其最终(因此阻止我覆盖其compareTo()方法来调用compareToIgnoreCase()),还有其他任何我能实现的吗?

任何帮助都会非常感谢。

2 个答案:

答案 0 :(得分:5)

要执行不区分大小写的二进制搜索,请使用String::compareToIgnoreCase作为比较器:

int i = Collections.binarySearch(list, key, String::compareToIgnoreCase);

这比比较减少到相同情况的两个字符串的执行速度更快,因为compareToIgnoreCase()逐个比较字符,仅在需要时减少字符大小写,如果字符串在第一个字符中不同,则允许快速返回。

注意:要使binarySearch()使用此比较器正常工作,必须使用完全相同的比较器对集合进行排序:

Collections.sort(list, String::compareToIgnoreCase);

答案 1 :(得分:1)

使用外部比较器,因为java.util.Collections具有此签名的binarySearch方法:

public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)

您的比较器看起来像

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());
    }
}

即使你可以扩展String来覆盖compareTo方法,我认为这不是一个好主意。