java ArrayList.remove() 不删除对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12697407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:52:42  来源:igfitidea点击:

ArrayList.remove() is not removing an object

javaarraylist

提问by vaindil

I know this is a messy implementation, but I basically have this code (I wrote all of it), and I need to be able to remove a student or instructor from the list when using the appropriate menu choice. Everything else in the code works, just not menu options 3 and 4. I'm entering the exact same information for the object when trying to delete. Here's the code. All three classes are below.

我知道这是一个凌乱的实现,但我基本上有这个代码(我写了所有这些),并且我需要能够在使用适当的菜单选项时从列表中删除学生或教师。代码中的其他所有内容都有效,只是菜单选项 3 和 4 无效。尝试删除时,我为对象输入了完全相同的信息。这是代码。所有三个类都在下面。

Driver class:

驱动类:

import java.util.ArrayList;
import java.util.Scanner;

public class Driver {
private ArrayList<Student> students;
private ArrayList<Instructor> instructors;

public static void main(String[] args) {        
    Driver aDriver = new Driver();
    aDriver.run();      
}

public Driver() {
    students = new ArrayList<Student>();
    instructors = new ArrayList<Instructor>();
}

private void run() {
    Student aStudent;
    Instructor anInstructor;
    Scanner inp = new Scanner(System.in);
    int choice = -1;
    String str = "Enter a menu option:\n";

    str += " 0: Quit\n";
    str += " 1: Add new student\n";
    str += " 2: Add new instructor\n";
    str += " 3: Delete existing student\n";
    str += " 4: Delete existing instructor\n";
    str += " 5: Print list of students\n";
    str += " 6: Print list of instructors\n";
    str += "Your choice: ";

    do {
        System.out.print(str);
        choice = inp.nextInt();

        switch(choice) {
        case 0:
            System.out.println("Thanks! Have a great day!");
            break;
        case 1:
            aStudent = getStudentInfo();
            addStudent(aStudent);
            break;
        case 2:
            anInstructor = getInstructorInfo();
            addInstructor(anInstructor);
            break;
        case 3:
            aStudent = getStudentInfo();
            deleteStudent(aStudent);
            break;
        case 4:
            anInstructor = getInstructorInfo();
            deleteInstructor(anInstructor);
            break;
        case 5:
            printStudents();
            break;
        case 6:
            printInstructors();
            break;
        default:
            System.out.println("Invalid menu item " + choice);  
        }
    }
    while(choice != 0);
}

public Student getStudentInfo() {
    Student aStudent;
    String name = null;
    String id = null;
    double GPA = 0.0;
    Scanner inp = new Scanner(System.in);

    System.out.print("\n\nEnter the student's name: ");
    name = inp.nextLine();
    System.out.print("Enter the student's ID: ");
    id = inp.nextLine();
    System.out.print("Enter the student's GPA: ");
    GPA = inp.nextDouble();

    aStudent = new Student(name, id, GPA);
    return aStudent;
}

public Instructor getInstructorInfo() {
    Instructor anInstructor;
    String name = null;
    String id = null;
    String dept = null;
    String email = null;
    Scanner inp = new Scanner(System.in);

    System.out.print("\n\nEnter the instructor's name: ");
    name = inp.nextLine();
    System.out.print("Enter the instructor's ID: ");
    id = inp.nextLine();
    System.out.print("Enter the instructor's department: ");
    dept = inp.nextLine();
    System.out.print("Enter the instructor's email address: ");
    email = inp.nextLine();

    anInstructor = new Instructor(name, id, dept, email);
    return anInstructor;
}

public void addStudent(Student aStudent) {
    students.add(aStudent);
}

public void addInstructor(Instructor anInstructor) {
    instructors.add(anInstructor);
}

public void deleteStudent(Student aStudent) {
    students.remove(aStudent);
}

public void deleteInstructor(Instructor anInstructor) {
    instructors.remove(anInstructor);
}

public void printStudents() {
    System.out.println("\n\n" + Student.printHeader());

    for(int i = 0; i < students.size(); i++) {
        System.out.print(students.get(i));
    }

    System.out.print("\n\n");
}

public void printInstructors() {
    System.out.print("\n\n" + Instructor.printHeader());

    for(int i = 0; i < instructors.size(); i++) {
        System.out.print(instructors.get(i));
    }

    System.out.print("\n\n");
}
}

Student class:

学生班:

public class Student {
private String name;
private String id;   //String to allow for the possibility of leading zeroes
private double GPA;

public Student() {
    name = "TestFirst TestLast";
    id = "00000";
    GPA = -1.00;
}

public Student(String name1, String id1, double GPA1) {
    name = name1;
    id = id1;
    GPA = GPA1;
}

public static String printHeader() {
    String str = String.format("%-25s%-7s%-6s\n", "Name", "ID", "GPA");
    return str;
}

public String toString() {
    String str = String.format("%-25s%-7s%-6.3f\n", name, id, GPA);
    return str;
}

public String getName() {
    return name;
}

public void setGPA(double GPA2) {
    GPA = GPA2;
}
}

Instructor class:

导师班:

public class Instructor {
private String name;
private String id;
private String dept;
private String email;

public Instructor() {
    name = "TestFirst TestLast";
    id = "-00001";
    dept = "TestDept";
    email = "[email protected]";
}

public Instructor(String name1, String id1, String dept1, String email1) {
    name = name1;
    id = id1;
    dept = dept1;
    email = email1;
}

public static String printHeader() {
    String str = String.format("%-30s%-6s%-15s%-15s\n", "Name", "ID", "Department", "Email Address");
    return str;
}

public String toString() {
    String str = String.format("%-30s%-6s%-15s%-15s\n", name, id, dept, email);
    return str;
}

public String getName() {
    return name;
}
}

回答by Dan D.

You must correctly override the equals()method for both Studentand Instructorclasses.

您必须正确覆盖和类的equals()方法。StudentInstructor

When overriding equals, it is good to override hashCode()as well. new Student(name, id, GPA);

当覆盖 equals 时,最好也覆盖hashCode()。新学生(姓名,身,GPA);

For example, something like this:

例如,这样的事情:

public boolean equals(Object o) {
  if (!(o instanceof Student)) {
    return false;
  }
  Student other = (Student) o;
  return name.equals(other.name) && id.equals(other.id) && GPA == other.GPA;
}

public int hashCode() {
  return name.hashCode();
}

This way, you give a chance to the ArrayListfigure out which object correspond to the one you passed as a parameter when deleting. If you don't override the above methods, it will use the default implementations in Object, which compare memory addresses which are definitely different as you remove a new Studentobject.

这样,您就有机会ArrayList找出与删除时作为参数传递的对象相对应的对象。如果您不覆盖上述方法,它将使用 中的默认实现Object,它比较在您删除新Student对象时绝对不同的内存地址。

You can read even more information about the 2 methods in the javadocs for Object.

您可以在Object.

回答by Amit Deshpande

You need to Override equals and hashcode methods for collections to work properly.

您需要覆盖 equals 和 hashcode 方法才能使集合正常工作。

@Override
public boolean equals(Object obj) {
    if (obj == null)
        return false;
    if (!(obj instanceof Student))
        return false;
    Student other = (Student) obj;
    return id == null ? false : id.equals(other.id);//Compare Id if null falseF
}

Since you are only using ArrayList there is hashcode method will not be used but it is still good practice to provide it.

由于您只使用 ArrayList,因此不会使用 hashcode 方法,但提供它仍然是一个好习惯。

 @Override
public int hashCode() {
    return id == null ? 0 : id.hashCode();
}

回答by Hyman

You didn't override the method equalsfor Studentand Instructor.

你没有覆盖的方法equals进行StudentInstructor

This method is used by the ArrayListto check wether 2 objects are the same. Without a custom implementation it will just check references, which will be different in your case since they are two different objects.

此方法用于ArrayList检查 2 个对象是否相同。如果没有自定义实现,它只会检查引用,这在您的情况下会有所不同,因为它们是两个不同的对象。

To provide custom equality you will have to check all the fields of the involved classes to be the same. This can be done recursively by calling equalson instance variables.

要提供自定义相等性,您必须检查所涉及类的所有字段是否相同。这可以通过调用equals实例变量递归地完成。

回答by NominSim

Overriding the equals method of Student and Instructor will work:

覆盖 Student 和 Instructor 的 equals 方法将起作用:

Here is an example for the Student class:

以下是 Student 类的示例:

public boolean equals(Object other){
    if(other == null) return false;
    if(other == this) return true;
    if(!(other instanceof Student)) return false;
    Student otherStudent = (Student)other;
    return otherStudent.id.equals(this.id);
}

You may also want to override hashCode():

您可能还想覆盖hashCode()

public String hashCode(){
    return new HashCodeBuilder(17, 31).
        append(name).
        append(id).
        toHashCode();
}