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
ArrayList.remove() is not removing an object
提问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 Student
and Instructor
classes.
您必须正确覆盖和类的equals()
方法。Student
Instructor
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 ArrayList
figure 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 Student
object.
这样,您就有机会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 equals
for Student
and Instructor
.
你没有覆盖的方法equals
进行Student
和Instructor
。
This method is used by the ArrayList
to 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 equals
on 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();
}