使 Collections.binarySearch() 与 compareToIgnoreCase 一起工作?

Making Collections.binarySearch() work with compareToIgnoreCase?

所以我在一个巨大的 ArrayList 中搜索一个特定的字符串值,但是如果我要查找的字符串相等(非区分大小写)到我传递给 binarySearch() 方法的字符串。

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

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

所以我不能将 String 重写为它的最终版本(因此阻止我重写它的 compareTo() 方法来调用 compareToIgnoreCase() ),还有其他我可以实现的吗?

如有帮助将不胜感激。

使用外部比较器,因为 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 方法,我认为这也不是一个好主意。

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

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

这将比比较两个简化为相同大小写的字符串执行得更快,因为 compareToIgnoreCase() 逐个比较字符,仅在需要时减少字符的大小写,这允许 return 快速处理字符串第一个字符不同。

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

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