简体   繁体   English

如何使用比较器执行 binarySearch?

[英]How to perform a binarySearch with a comparator?

I'm trying to perform a binary search with a case-insensitive comparator, but I keep getting errors whatever I try...我正在尝试使用不区分大小写的比较器执行二进制搜索,但无论我尝试什么,我都会遇到错误......

Trial 1:试验一:

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

Source: https://stackoverflow.com/a/30191946/900394资料来源: https://stackoverflow.com/a/30191946/900394

This gives an error:这给出了一个错误:

Method references are not supported at language level '7'语言级别“7”不支持方法引用

Assuming I want to work with Java 7, I tried these additional methods:假设我想使用 Java 7,我尝试了以下其他方法:

Trial 2 :试验 2

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

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

Source: https://stackoverflow.com/a/14154185/900394资料来源: https://stackoverflow.com/a/14154185/900394

Error:错误:

Required type: Comparator<?所需类型:比较器<? super Object>超级对象>
Provided: Comparator提供:比较器

Note that this method is working for sorting a list (ie this comparator is suitable for Collections.sort() )请注意,此方法适用于对列表进行排序(即此比较器适用于Collections.sort()

Trial 3:试验 3:

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

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

Error:错误:

Required type: Comparator<?所需类型:比较器<? super Object>超级对象>
Provided: Comparator提供:比较器

Note that this method is also working on Collections.sort()请注意,此方法也适用于Collections.sort()

Trial 4:试验四:

Build a class that implements Comparator<String> :构建一个实现Comparator<String>的 class :

public class CaseInsensitiveComparatorClass implements Comparator<String> {

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

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

Source: https://stackoverflow.com/a/30191797/900394资料来源: https://stackoverflow.com/a/30191797/900394

Error:错误:

Required type: Comparator<?所需类型:比较器<? super java.lang.Object>超级 java.lang.Object>
Provided: CaseInsensitiveComparatorClass提供:CaseInsensitiveComparatorClass

Note that this method is also working on Collections.sort()请注意,此方法也适用于Collections.sort()

Can you provide me with one method that does work, or point out what I'm doing wrong?您能否为我提供一种有效的方法,或者指出我做错了什么?


EDIT:编辑:

This is the declaration of arr :这是arr的声明:

private List<String> lst;

So it's actually a list, which I convert to an array on the method invocation:所以它实际上是一个列表,我在方法调用时将其转换为数组:

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

regarding your first example, you use method reference feature from Java 8 ( String::compareToIgnoreCase ), but you compile/execute code with Java 7. change version of Java at least to Java 8. also keep in mind, that before using Arrays.binarySearch , your array should be sorted. regarding your first example, you use method reference feature from Java 8 ( String::compareToIgnoreCase ), but you compile/execute code with Java 7. change version of Java at least to Java 8. also keep in mind, that before using Arrays.binarySearch ,你的数组应该被排序。

for collection you could use the following method: Collections.binarySearch()对于收集,您可以使用以下方法: Collections.binarySearch()

in order to convert list to array with generic parameters, use the following:为了将列表转换为具有泛型参数的数组,请使用以下命令:

lst.toArray(new String[0]);

Instead of an array, you actually have a list: List<String> .您实际上有一个列表,而不是一个数组: List<String> Use Collections.binarySearch instead of converting the list to an array followed by Arrays.binarySearch .使用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);

If for some silly reason you must use Arrays.binarySearch , you can pass the concrete list type as an argument to List.toArray .如果出于某种愚蠢的原因您必须使用Arrays.binarySearch ,您可以将具体列表类型作为参数传递给List.toArray This will make the method return an array of Strings instead an array of Objects:这将使该方法返回一个字符串数组而不是一个对象数组:

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

Note that the array should be sorted according to Arrays.binarySearch Javadoc:注意数组要按照 Arrays.binarySearch Javadoc 排序:

Searches the specified array for the specified object using the binary search algorithm.使用二分搜索算法在指定数组中搜索指定的 object。 The array must be sorted into ascending order according to the specified comparator (as by the sort(T[], Comparator) method) prior to making this call.在进行此调用之前,必须根据指定的比较器(如通过 sort(T[], Comparator) 方法)对数组进行升序排序。 If it is not sorted, the results are undefined.如果未排序,则结果未定义。 If the array contains multiple elements equal to the specified object, there is no guarantee which one will be found.如果数组包含多个等于指定 object 的元素,则无法保证会找到哪一个。

The String itself implements Comparable interface, So, there is no need to implement new one String 本身实现了 Comparable 接口,所以,没有必要实现一个新的

Here is the short code snippet that visualizes how to use Arrays.binarySearch.这是可视化如何使用 Arrays.binarySearch 的简短代码片段。

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

Try this code:试试这个代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM