在对象中实现二分查找
Posted
技术标签:
【中文标题】在对象中实现二分查找【英文标题】: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)”会是什么样子?这甚至可能吗?
【问题讨论】:
使用 Collections.binarySearch - 请参阅 example usages 【参考方案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.binarySearch
和Comparator
。
【讨论】:
【参考方案4】:import java.util.Collections;
Collections.binarySearch(users, id);
【讨论】:
这在编写的代码上不起作用,原因有两个:1)用户没有实现 Comparable,也没有给出 Comparator。 2) 您必须将 binarySearch 传递给存储在列表中的类型的实际对象;你正在传递一个 int 。【参考方案5】:您应该只在排序后的 ArrayList 上使用 binarySearch 方法。所以首先对 ArraList 进行排序,并使用相同的比较器引用(用于进行排序)来执行 binarySearch 操作。
【讨论】:
以上是关于在对象中实现二分查找的主要内容,如果未能解决你的问题,请参考以下文章