【问题标题】:implementing sort and search methods for arraylist of objects in Java在Java中实现对象数组列表的排序和搜索方法
【发布时间】:2021-07-15 11:02:03
【问题描述】:

我知道基本的编程,但我是 OOP 和 Java 的新手。我正在尝试缩短和搜索对象的 ArrayList。我知道有很多方法可以做到这一点,但我喜欢这里有两种方法来收集, Java List.contains(Object with field value equal to x) 和这里Sort ArrayList of custom Objects by property 代码在主类中时有效,但我想将它们移到学生类中并调用我自己的排序和搜索方法。排序功能仍然有效,但搜索返回错误的索引整数。我找不到我想念的东西。完整代码如下。

  /* implementation of binary search found at
https://stackoverflow.com/questions/18852059/
and sort solution at
https://stackoverflow.com/questions/2784514/
 */

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

public class test {
    static ArrayList<Student> course = new ArrayList<>();

    public static void main(String[] args) {
        System.out.print("Enter name to search: ");
        Scanner input = new Scanner(System.in);
        String stName = input.nextLine();

        course.add(new Student("will", 353429, 13.2));
        course.add(new Student("joe", 353430, 12.1));
        course.add(new Student("bill", 353431, 14.9));
        course.add(new Student("jim", 353432, 15.3));
        course.add(new Student("jack", 353473, 11.2));
        course.add(new Student("jean", 353439, 16.8));
        course.add(new Student("jill", 353333, 14.9));
        course.add(new Student("jane", 353432, 15.7));
        course.add(new Student("john", 353421, 10.6));
        course.add(new Student("ben", 353438, 16.0));
        course.add(new Student("dave", 353529, 14.9));
        course.add(new Student("jim", 352989, 15.3));
        course.add(new Student("doug", 353178, 11.2));

        sortStudents();

/*  // search part works when its here , inside main class
        int idx = Collections.binarySearch(course, new Student( stName ), new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
*/

        int idx = searchStudent( stName );

        System.out.println("Sorted list");
        for (int cnt=0;cnt<course.size();cnt++){
            System.out.println(cnt + " "+ course.get(cnt).toString());
        }

        if (idx>0){
            System.out.println(stName +" found on line: " + idx);
            }else{
            System.out.println(" Not in the list" +idx);
        }
    }

    static void sortStudents(){
        Collections.sort(course,Student.sortByName);
    }

    static int searchStudent(String nm){
        return Collections.binarySearch(course, new Student(nm));
    }


    static  class Student implements Comparable<Student>{
        private String name;
        private int age;
        private double points;

        public Student(String nm) {  this.name = nm; } // constructor

        public Student(String nm, int n, double p) {  // constructor
            this.name = nm;
            this.age = n;
            this.points = p;  }

        public String getName(){ return name; }
// but search code fails when moved here 
        public static Comparator<Student> binarySearch = new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getName().compareTo(o2.getName());
            }
        };

        public static Comparator<Student> sortByName = new Comparator<Student>() {
            @Override
            public int compare(Student obj1, Student obj2) {
                //sort in ascending order
                return obj1.name.compareTo(obj2.name);
                //sort in descending order
                //return obj2.name.compareTo(obj1.name);
            }
        };

        @Override
        public int compareTo(Student o) {
            return 0;
        }

        
        @Override
        public String toString() {
            return "Name:" + name + ", Age:" + age;
        }
    }
}


  

【问题讨论】:

    标签: java sorting search arraylist collections


    【解决方案1】:

    问题

    那是因为你的compareTo,因为你没有实现如何比较它们之间的Student,你只实现了一个名称comparator,这是Collections.binarySearch使用的

    @Override
    public int compareTo(Student o) {
        return 0;
    }
    

    您可以修复明确的Comparator

    static int searchStudent(String nm) {
        return Collections.binarySearch(course, new Student(nm), Student.sortByName);
    }
    

    改进

    另外Comparator&lt;Student&gt; binarySearchComparator&lt;Student&gt; sortByName 相同,没有理由让两件事做同样的事情。

    你也需要明白这一点

    • 您需要Comparator 告诉如何订购对象
    • 使对象Comparable 知道它自己如何与其他对象一起订购它

    这两个都做了,没用,删除Comparators 定义


    修复

    所以只有compareTo 方法才能完成这项工作

    @Override
    public int compareTo(Student o) {
        int diff = this.name.compareTo(o.name);
        if (diff != 0) {
            return diff;
        }
        return Integer.compare(this.age, o.age);
    }
    

    可以使用Comparator 简化它,它允许一些方法链接。注意它是private,它不应该在类外手动使用,因为类现在知道自己如何对元素进行排序

    static private Comparator<Student> studComp = Comparator.comparing(Student::getName)
                                                        .thenComparing(Student::getAge);
    
    @Override
    public int compareTo(Student o) {
        return studComp.compare(this, o);
    }
    

    在主课中给予

    static void sortStudents() {
        course.sort(Comparator.naturalOrder());
    }
    
    static int searchStudent(String nm) {
        return Collections.binarySearch(course, new Student(nm));
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-20
      • 2012-04-26
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 2011-07-08
      • 1970-01-01
      • 2010-10-31
      相关资源
      最近更新 更多