【问题标题】:How to perform a binarySearch with a comparator?如何使用比较器执行二进制搜索?
【发布时间】:2020-10-25 00:54:00
【问题描述】:

我正在尝试使用不区分大小写的比较器执行二进制搜索,但无论我尝试什么都会不断出错...

试用 1:

Arrays.binarySearch(arr, "text", String::compareToIgnoreCase);

来源:https://stackoverflow.com/a/30191946/900394

这给出了一个错误:

语言级别“7”不支持方法引用

假设我想使用 Java 7,我尝试了以下其他方法:

试用 2

Comparator<String> caseInsensitiveComparator = new Comparator<String>() {
        @Override
        public int compare(String s, String t1) {
            return s.compareToIgnoreCase(t1);
        }
    };

Arrays.binarySearch(arr, "text", caseInsensitiveComparator);

来源:https://stackoverflow.com/a/14154185/900394

错误:

必需类型:比较器
提供:比较器

请注意,此方法适用于对列表进行排序(即此比较器适用于Collections.sort()

试用 3:

Arrays.binarySearch(arr, "text", String.CASE_INSENSITIVE_ORDER);

来源:https://stackoverflow.com/a/17491652/900394

错误:

必需类型:比较器
提供:比较器

请注意,此方法也适用于Collections.sort()

试验 4:

构建一个实现Comparator&lt;String&gt;的类:

public class CaseInsensitiveComparatorClass implements Comparator<String> {

    @Override
    public int compare(String s, String t1) {
        return s.compareToIgnoreCase(t1);
    }
}

Arrays.binarySearch(arr, "text", new CaseInsensitiveComparatorClass ());

来源:https://stackoverflow.com/a/30191797/900394

错误:

必需类型:比较器
提供:CaseInsensitiveComparatorClass

请注意,此方法也适用于 Collections.sort()

您能否提供一种可行的方法,或者指出我做错了什么?


编辑:

这是arr的声明:

private List&lt;String&gt; lst;

所以它实际上是一个列表,我在方法调用时将其转换为数组:

Arrays.binarySearch(lst.toArray(),...

【问题讨论】:

  • 我猜arr 的类型有问题。请发布您如何初始化它
  • 如果arr 声明为String [] arr,你应该没有问题
  • @VasiliySarzhynskyi,它实际上是一个列表,我将其转换为一个数组。请参阅编辑
  • 您应该将代码更改为以下内容:Arrays.binarySearch(lst.toArray(new String[0]),...
  • @VasiliySarzhynskyi,是的。你说得对。谢谢,我选择了你的答案。顺便说一句,我看到由于某种原因,所有答案都被否决了。我没有否决任何答案...不知道发生了什么...

标签: java comparator


【解决方案1】:

关于您的第一个示例,您使用 Java 8 (String::compareToIgnoreCase) 中的方法引用功能,但您使用 Java 7 编译/执行代码。至少将 Java 版本更改为 Java 8。 还请记住,在使用Arrays.binarySearch 之前,您的数组应该进行排序。

您可以使用以下方法收集:Collections.binarySearch()

要将列表转换为具有泛型参数的数组,请使用以下命令:

lst.toArray(new String[0]);

【讨论】:

  • 这是正确的答案(将列表转换为具有显式类型的数组)。谢谢你。奇怪的是,IDE 给了我一个完全不相关的错误指示。
【解决方案2】:

注意数组要按照Arrays.binarySearch Javadoc排序:

使用二分搜索算法在指定数组中搜索指定对象。数组必须按升序排序 根据指定的比较器(如 sort(T[], Comparator) 方法)在进行此调用之前。如果没有排序,结果 是未定义的。如果数组包含多个元素等于 指定的对象,不能保证会找到哪一个。

String本身实现了Comparable接口,所以不需要再实现一个

这里是可视化如何使用 Arrays.binarySearch 的短代码 sn-p。

public class BinarySearch {
    public static void main(String[] args) {
        final String[] arr = {"one", "two", "three", "four", "text"};

        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
        System.out.println(Arrays.binarySearch(arr, "text", String.CASE_INSENSITIVE_ORDER));
    }
}

【讨论】:

  • 更新:既然您描述了 arr 的类型,您可以使用 Collections.binarySearch。
【解决方案3】:

您实际上有一个列表,而不是一个数组:List&lt;String&gt;。使用Collections.binarySearch 而不是将列表转换为数组,后跟Arrays.binarySearch

List<String> lst = Arrays.asList("a", "text", "z"); // just an example list
int index = Collections.binarySearch(lst, "text", String.CASE_INSENSITIVE_ORDER);

如果出于某种愚蠢的原因您必须使用Arrays.binarySearch,您可以将具体列表类型作为参数传递给List.toArray。这将使该方法返回一个字符串数组而不是一个对象数组:

Arrays.binarySearch(lst.toArray(new String[0]), String.CASE_INSENSITIVE_ORDER)

【讨论】:

    【解决方案4】:

    试试这个代码:

        String[] arr = {"a","b","c"};
    
        int i = Arrays.binarySearch(arr, "B", new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareToIgnoreCase(o2);
            }
        });
    
        System.out.println(i);
    

    【讨论】:

      猜你喜欢
      • 2012-10-02
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 2014-06-21
      • 2010-11-01
      • 2012-06-27
      • 2012-10-16
      • 2015-07-29
      相关资源
      最近更新 更多