【问题标题】:How to use `Collections.binarySearch()` to do a binary search though an ArrayList of objects?如何使用 `Collections.binarySearch()` 通过对象的 ArrayList 进行二进制搜索?
【发布时间】:2024-04-26 23:30:01
【问题描述】:

我已经尝试了相关问题的所有答案,如下所示:

Implement binary search using the `Collections.binarySearch` signature

Can't use binary search with Object Arraylist?

但没有一个对我有用。

问题是我想做binarySearch()ArrayList 中找到具有特定属性的对象。

我为此使用以下代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class SearchingThread extends Thread {

    private String search;
    private ArrayList<Vehicle> vehicles;

    public SearchingThread(String search, ArrayList<Vehicle> vehicles) {
        this.search = search;
        this.vehicles = vehicles;
    }

    public void run() {

        Comparator<Vehicle> comp = new Comparator<Vehicle>() {

            @Override
            public int compare(Vehicle o1, Vehicle o2) {
                return o1.getModel().compareTo(o2.getModel());
            }

        };

        int index = Collections.binarySearch(vehicles, search, comp);



    }

}

这里search 是我想在ArrayList 中搜索model 的变量vehicles

我收到以下错误:

Collections 类型中的方法 binarySearch(List, T, Comparator) 不适用于参数(ArrayList, String, Comparator)

我无法使用它,谁能帮助我了解错误的原因和解决方案。

编辑:

很抱歉之前没有发布这个,排序不是问题。我已经事先对数组列表进行了相应的排序。

【问题讨论】:

  • 仅作记录:您了解二进制搜索的先决条件是您的数组/列表已经排序吗?是这样吗?
  • “我太懒了”如果你懒得做 s/eihcle/ehicle/g,那你就太懒了。
  • @AndyTurner 是的 :)
  • @GhostCat 道歉,请参阅编辑后的问题。

标签: java comparator binary-search


【解决方案1】:

Collections#binarySearchList 中搜索列表所包含的相同类型的值。在这里,您尝试使用字符串搜索车辆列表,从而得到您共享的错误。
一种方法是创建一个假车辆,以便可以搜索其模型:

Vehicle modelDummy = new Vehicle();
modelDummy.setModel(search);
int index = Collections.binarySearch(vehicles, modelDummy, comp);

请注意,为了像这样使用binarySearch,列表必须根据您提供的Comparator 进行排序(即,在这种情况下根据模型排序)。如果此假设不成立,则必须使用 O(n) 搜索。例如:

Vehicle vehicle = vehicles.stream().filter(v -> v.getModel().eqauls(search)).findFirst();

【讨论】:

    【解决方案2】:

    创建列表视图:

    List<String> view = new AbstractList<String>() {
      @Override public int size() {
        return vehicles.size();
      }
    
      @Override public String get(int i) {
        return vehicles.get(i).getModel();
      }
    };
    

    然后对视图应用二分搜索。

    int index = Collections.binarySearch(view, search);
    

    请注意,虽然它可以像这样使用匿名类,但最好定义一个命名类(例如嵌套类,甚至是本地类),以便它可以同时使用 extend AbstractList 和 @ 987654324@,让二分查找知道它可以通过索引高效访问。

    【讨论】:

      最近更新 更多