我可以调用binarySearch方法而不实现比较器/可比较吗?

时间:2013-02-15 14:38:24

标签: java collections

如果我想调用binarySearch()方法来执行搜索操作,是否需要实现比较器或类比? 我在尝试调用binarySearch()方法时遇到异常。

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

class Student implements{
private int id;
private String name;

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

public Student() {
    // TODO Auto-generated constructor stub
}

public int getId(){
    return id;
}
public String getName(){
    return name;
}

}
public class CollectionSearchDemo {


public static void main(String[] args) {

    List<Student> list = new ArrayList<Student>();
    list.add(new Student(3, "ouier"));
    list.add(new Student(2, "fdgds"));
    list.add(new Student(7, "kiluf"));
    list.add(new Student(1, "6trfd"));
    list.add(new Student(8, "hjgas"));
    list.add(new Student(5, "ewwew"));

    Collections.sort(list, new Comparator<Student>() {

        @Override
        public int compare(Student arg0, Student arg1) {

            return arg0.getId() - arg1.getId();
        }
    });

    Iterator iterator = list.iterator();
    while(iterator.hasNext()){
        Student student = (Student) iterator.next();
        System.out.print(student.getId()+":"+student.getName()+" ");
    }

    System.out.println("I want to do searching ");
    System.out.println("\n2 is at:"+Collections.binarySearch(list, 2, new Student()));
            // facing exception when i invoke binarySearch method.
}
}

当我尝试搜索“new Student()”或“CollectionSearchDemo”作为参数时发生异常。 我不知道我应该在binraySearch方法中作为参数传递什么。

请帮帮我

5 个答案:

答案 0 :(得分:4)

有两种方法可以使用Collections.binarySearch。第一个只有一个元素列表和一个键,但这些元素必须实现Comparable。第二种方式是钥匙和比较器。如果您不希望Student实施Comparable,则必须使用此版本。

所以你必须写下这样的东西:

 Collections.binarySearch(list, studentToBeFound, comparator);

studentToBeFoundStudent个实例,比较器为Comparator<Student>,就像您在Collection.sort()中使用的那样。

只需重复使用与Id比较的先前比较器:

private static final class StudentComparator implements Comparator<Student> {
  @Override
  public int compare(Student arg0, Student arg1) {

    return arg0.getId() - arg1.getId();
  }
}

然后,如果你想找到Id等于2的学生:

Student studentToBeFound = new Student(2, "dummy string");

并将它们与binarySearch一起使用:

int indexInList = Collections.binarySearch(list, studentToBeFound, new StudentComparator());

答案 1 :(得分:1)

binarySearch方法的第三个参数必须是Comparator,抛出异常是因为您的类Student没有实现Comparator接口。

binarySearch(List list, Object key, Comparator c)

请在此处阅读:http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html

参数c必须是实现Comparator的类的实例。

答案 2 :(得分:1)

简短回答是肯定的 - 二进制搜索不知道您要搜索的Student是“更大”还是“更小”,然后列表中的每一个都无法搜索。
您希望使用比较器中已有的代码在Student上实现可比较:

public class Student implements Comparable<Student> {
//stuff
 @Override
 public int compareTo(Student o) {
  return getId() - o.getId();
 }
}

然后你的代码看起来像这样:

final Set<Student> set = new TreeSet<Student>();
//add students etc...
final Student found = Collections.binarySearch(set, studentToLookFor);

答案 3 :(得分:1)

如果我们不知道如何订购,则无法对列表进行排序。二进制搜索算法要求对列表进行排序,并使用列表的排序来搜索列表,每次迭代时将搜索字段切成两半。但是,学生x是在列表的前半部分还是列表的后半部分的概念要求我们知道这个列表是如何排序的。

选项1:public class Student implements Comparable<Student>

选项2:为学生写一个Comparator课程。

public class StudentComparator implements Comparator<Student>

答案 4 :(得分:1)

二进制搜索需要排序列表。

这种搜索基于分区:

  1. 取中间元素并将其与参考文献进行比较。
  2. 如果比较表明您的引用是“较低”,则二进制搜索在集合的前半部分继续,或者如果它是“更高”则继续在后半部分继续。
  3. 当比较返回0时,找到该元素。
  4. 考虑到这一点,实际上要求对列表进行排序。你可以用不同的方式做到这一点:

    • 借助Comparator对其进行排序,然后调用binarySerarch
    • 对实现Comparable接口的元素集合进行排序,然后调用binarySearch
    • 如果您提供所需的binarySearch,则将排序保留为Comparator方法。