【问题标题】:Implement binary search in objects在对象中实现二分查找
【发布时间】:2010-10-28 11:12:02
【问题描述】:

有没有办法在带有对象的 ArrayList 中实现二进制搜索?在此示例中,ArrayList 将使用字段“id”进行排序。

class User{
 public int id;
 public string name;
}

ArrayList<User> users = new ArrayList<User>();

sortById(users);

int id = 66
User searchuser = getUserById(users,id);

如果我应该使用二进制搜索返回具有指定 id 的用户,“User getUserById(ArrayList users, int userid)”会是什么样子?这甚至可能吗?

【问题讨论】:

标签: java search collections binary-search


【解决方案1】:

The Java Tutorials 的 Object Ordering 文章有一个编写您自己的 Comparator 以对自定义类型进行比较的示例。

然后,ArrayList(或任何其他List),与Comparator 一起可以被传递到Collections.binarySearch 方法。

这是一个例子:

import java.util.*;

class BinarySearchWithComparator
{
  public static void main(String[] args)
  {
    // Please scroll down to see 'User' class implementation.
    List<User> l = new ArrayList<User>();
    l.add(new User(10, "A"));
    l.add(new User(20, "B"));
    l.add(new User(30, "C"));

    Comparator<User> c = new Comparator<User>() {
      public int compare(User u1, User u2) {
        return u1.getId().compareTo(u2.getId());
      }
    };

    // Must pass in an object of type 'User' as the key.
    // The key is an 'User' with the 'id' which is been searched for.
    // The 'name' field is not used in the comparison for the binary search,
    // so it can be a dummy value -- here it is omitted with a null.
    //
    // Also note that the List must be sorted before running binarySearch,
    // in this case, the list is already sorted.

    int index = Collections.binarySearch(l, new User(20, null), c);
    System.out.println(index);    // Output: 1

    index = Collections.binarySearch(l, new User(10, null), c);
    System.out.println(index);    // Output: 0

    index = Collections.binarySearch(l, new User(42, null), c);
    System.out.println(index);    // Output: -4
                                  // See javadoc for meaning of return value.
  }
}

class User {
  private int id;
  private String name;

  public User(int id, String name) {
    this.id = id;
    this.name = name;
  }

  public Integer getId() {
    return Integer.valueOf(id);
  }
}

【讨论】:

    【解决方案2】:

    您也可以将比较器放在 User 类中:

    public class User implements Comparable<User>, Comparator<User>
    {
      public User(int id, String name)
      {
        this.id = id;
        this.name = name;
      }
      @Override
      public int compareTo(User u)
      {
        return id - u.getID();
      }
      @Override
      public int compare(User u1, User u2)
      {
        return u1.getID() - u2.getID();
      }
    
      public int getID() { return id; }
      public String getName() { return name; }
      private int id;
      private String name;
    }
    

    然后您将对名为 users 的 ArrayList 执行以下操作:

    ArrayList<User> users = new ArrayList<User>();
    users.add(new User(3, "Fred"));
    users.add(new User(42, "Joe"));
    users.add(new User(5, "Mary"));
    users.add(new User(17, "Alice"));
    
    Collections.sort(users);
    int index = Collections.binarySearch(users, new User(5, null));
    if(index >= 0)
      System.out.println("The user name of id 5 is: "+users.get(index).getName());
    else
      System.out.println("ID 5 is not in the list");
    

    【讨论】:

      【解决方案3】:

      使用Collections.binarySearchComparator

      【讨论】:

        【解决方案4】:
        import java.util.Collections;
        Collections.binarySearch(users, id);
        

        【讨论】:

        • 这在编写的代码上不起作用,原因有两个:1)用户没有实现 Comparable,也没有给出 Comparator。 2) 您必须将 binarySearch 传递给存储在列表中的类型的实际对象;你正在传递一个 int 。
        【解决方案5】:

        您应该只在排序后的 ArrayList 上使用 binarySearch 方法。所以首先对 ArraList 进行排序,并使用相同的比较器引用(用于进行排序)来执行 binarySearch 操作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-23
          • 1970-01-01
          • 1970-01-01
          • 2015-06-10
          • 2018-04-13
          • 1970-01-01
          • 1970-01-01
          • 2023-03-05
          相关资源
          最近更新 更多