【问题标题】:BinarySearch on Object Array List in JavaJava中对象数组列表的BinarySearch
【发布时间】:2015-04-21 17:17:15
【问题描述】:

我正在尝试对对象数组列表执行二进制搜索。用户必须输入管理员号码才能执行搜索。这是我的代码:

文件控制器类从 .text 文件中读取文件

public class FileController extends StudentApp{
private String fileName;

public FileController() {
    String fileName = "student.txt";
}

public FileController(String fileName) {
    this.fileName = fileName;
}

public ArrayList<String> readLine() {
    ArrayList<String> studentList = new ArrayList<String>();
    try {
        FileReader fr = new FileReader(fileName);
        Scanner sc = new Scanner(fr);
        while (sc.hasNextLine()) {
            studentList.add(sc.nextLine());
        }
        fr.close();
    } catch (FileNotFoundException exception) {
        System.out.println("File " + fileName + " was not found");
    } catch (IOException exception) {
        System.out.println(exception);
    }
    return studentList;
}

具有所有 setter & getter 和 compareTo 方法的学生类

public Student(String adminNo, String name, GregorianCalendar birthDate) {
    this.adminNo = adminNo;
    this.name = name;
    this.birthDate = birthDate;
}

public Student(String record) {
    Scanner sc = new Scanner(record);
    sc.useDelimiter(";");
    adminNo = sc.next();
    name = sc.next();
    birthDate = MyCalendar.convertDate(sc.next());
    test1 = sc.nextInt();
    test2 = sc.nextInt();
    test3 = sc.nextInt();
}
public String toString(){
    return (adminNo + " " + name + " " + MyCalendar.formatDate(this.birthDate));
}

public static ArrayList<Student> readStudent(String file) {
    FileController fc = new FileController(file);
    ArrayList<Student> recs = new ArrayList<Student>();
    ArrayList<String> recsReturn = new ArrayList<String>();

    recsReturn = fc.readLine();

    for (int index = 0; index < recsReturn.size(); index++) {
        String input = recsReturn.get(index);
        recs.add(new Student(input));
    }

    return recs;
}


public int compareTo(Student s) {
    return Compare(this, s);
}

public int Compare(Student s1, Student s2){
    if(s1.getAdminNo().equals(s2.getAdminNo())) {
      return 0;
    }else{
      return 1;
    }
}

可执行的 main 方法在这里,在 StudentSearch 类中

public static void main(String [] args){
    Scanner sc = new Scanner(System.in);
    ArrayList <Student> studentList = new ArrayList <Student> ();
    studentList = Student.readStudent("student.txt");
    Collections.sort(studentList);

    System.out.println("Enter student admin number: ");
    String searchAdminNo = sc.next();

    int pos = Collections.binarySearch(studentList, new   Student(searchAdminNo));
    System.out.println(pos);
}

我想使用用户输入的管理员号码进行搜索。但是,这是错误消息:

Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at StudentGradeApps.Student.<init>(Student.java:22)
at StudentGradeApps.StudentSearch.main(StudentSearch.java:14)

我认为问题在于 compareTo 方法和我的二进制搜索。因为当我删除它们时,我的程序可以很好地获取数组列表。仅当我尝试对我的对象列表执行搜索时才会出现该错误。任何帮助将不胜感激。

提前致谢。

【问题讨论】:

  • 问题在于您尝试解析字符串以获取学生记录。在尝试拆分之前打印字符串,你会得到错误。
  • 这是什么意思?因为我尝试仅按管理员号码搜索。不应该拆分然后从整个记录中找到管理员号码吗?
  • 这段代码是不是你写的?你在这里传递一个文件: Student.readStudent("student.txt");然后它在 Student 构造函数中进行内部拆分。
  • @lok​​i 那么我应该怎么做才能解决它呢?你能给我一些代码示例,比如如何解决它吗?我真的不明白你的意思

标签: java eclipse arraylist binary-search compareto


【解决方案1】:

正如错误消息所说,异常发生在 Student 构造函数中 -

public Student(String record) {
    Scanner sc = new Scanner(record);
    sc.useDelimiter(";");
    adminNo = sc.next();
    name = sc.next();
    birthDate = MyCalendar.convertDate(sc.next());
    test1 = sc.nextInt();
    test2 = sc.nextInt();
    test3 = sc.nextInt();
}

你在这里调用构造函数-

int pos = Collections.binarySearch(studentList, new   Student(searchAdminNo));

searchAdminNo 可能没有你在构造函数中读取的那么多标记(由; 分隔)。

【讨论】:

  • 换句话说,要让构造函数正常工作,searchAdminNo 的值应该类似于 - "some_string;some_string;some_string;some_integer;some_integer_some_integer"
  • my searchAdminNo 只是用户输入的管理员号码。然后它将转到文本文件并找到类似 033333C;Peter Loh;1/09/1983;55;70;30; 的记录。只有第一个元素是管理员编号
  • 您可以使用其他版本的方法Collections#binarySearch() 并为您的Student 类提供Comparator。您将不得不使用Student 中的另一个构造函数,它不使用Scanner。另请注意,二进制搜索仅在集合已排序时才有效。
  • 这意味着我的旧代码不能再使用了,因为没有解决方案可以从那里修复,我需要重新编码?
  • 看起来应该是这样,但只是为了确保 - 是 Student Comparable?对于要排序和搜索的对象,它们必须是Comparable。需要看看你是如何实现compareTo() 方法的。而且,您也绝对可以使用您的代码,但由于它不工作,它应该被修复,你知道的。
猜你喜欢
  • 2015-01-03
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
  • 2013-12-19
  • 2014-03-17
  • 2021-04-06
  • 2016-12-12
  • 2021-07-19
相关资源
最近更新 更多