Java ArrayList.remove()未删除对象
我知道这是一个混乱的实现,但我基本上有这段代码(我写了所有代码),我需要能够在使用适当的菜单选项时从列表中删除学生或讲师。代码中的其他所有内容都有效,只是菜单选项3和4无效。尝试删除时,我正在为对象输入完全相同的信息。这是密码。这三门课都在下面 驾驶员等级:Java ArrayList.remove()未删除对象,java,arraylist,Java,Arraylist,我知道这是一个混乱的实现,但我基本上有这段代码(我写了所有代码),我需要能够在使用适当的菜单选项时从列表中删除学生或讲师。代码中的其他所有内容都有效,只是菜单选项3和4无效。尝试删除时,我正在为对象输入完全相同的信息。这是密码。这三门课都在下面 驾驶员等级: import java.util.ArrayList; import java.util.Scanner; public class Driver { private ArrayList<Student> students;
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");
}
}
讲师课程:
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 = "test@test.net";
}
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;
}
}
对于
学生
和讲师
课程,必须正确重写equals()
方法
当重写equals时,最好也重写hashCode()
。
新生(姓名、身份证、GPA)
例如,类似这样的内容:
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();
}
这样,您就有机会让ArrayList
找出哪个对象对应于删除时作为参数传递的对象。如果不重写上述方法,它将使用对象
中的默认实现,在删除新的学生
对象时,这些实现会比较内存地址,这些地址肯定不同
您可以阅读javadocs for
Object
中关于这两个方法的更多信息,您需要覆盖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
}
因为您只使用ArrayList,所以不会使用hashcode方法,但提供它仍然是一个很好的实践
@Override
public int hashCode() {
return id == null ? 0 : id.hashCode();
}
您没有覆盖
学生
和讲师
的方法
ArrayList
使用此方法检查两个对象是否相同。如果没有自定义实现,它只会检查引用,这在您的情况下是不同的,因为它们是两个不同的对象
要提供自定义相等,必须检查所涉及类的所有字段是否相同。这可以通过对实例变量调用
equals
递归完成。覆盖Student和讲师的equals方法将起作用:
以下是学生班的一个示例:
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;
}
}
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);
}
您可能还希望覆盖hashCode()
:
当存在同名的不同学生时,hashCode不会产生问题吗?不会,因为hashCode()的目标是将实例分离到存储桶中。只有同一个bucket中的实例使用equals进行比较。所以,同名学生应该进入同一个桶。你看到我更新的答案了吗?有一些代码可以复制并粘贴到其中。尽管如此,更好的hashCode重写可能会考虑id,而不是名称或名称之外的id。冲突会减少(假设学生id是唯一的)。不过,如果你不介意帮我核实的话,我想确保我理解。
对象o
参数是一个占位符,它将接受传递给它的任何对象。if语句检查它是否是适当类型的对象(在本例中为学生
,但在讲师
类中为讲师
),如果对象不是该类型,则返回false。行Student other…
只是将对象
放入一个Student
对象中,以便对其进行比较,最终语句实际上检查上述内容是否相等。对吗?好吧,我明白你的意思,但我不知道如何实施。例如,当我重写toString
时,我需要做的就是从该方法返回一个String
对象。当我重写equals
时,我需要使用if语句进行比较,但是我应该比较哪两件事,特别是在使用ArrayList.remove()时remove()。您只需要实现该方法,以便当且仅当两个学生是同一个学生时(这可能意味着如果他们有相同的名称和相同的内容,则返回true
)
public String hashCode(){
return new HashCodeBuilder(17, 31).
append(name).
append(id).
toHashCode();
}