Defining Equality
Here is Student. It does not override equals or hashCode:
public class Student {
private int id;
private String name;
private double gpa;
public Student(int id, String name, double gpa) {
this.id = id;
this.name = name;
this.gpa = gpa;
}
public int getId() { return id; }
public String getName() { return name; }
public double getGpa() { return gpa; }
}
DynamicArray<Student>.indexOf originally compares elements with arr[i] == value.
Solution
== on objects compares references: it asks whether both sides are the same object in memory, not whether their fields match. The two Student objects here were built separately with new, so they are distinct objects even though their fields are identical, and == says false.
Switching to .equals does not fix it on its own. Every class inherits equals from Object if it does not define its own, and Student does not. Object’s equals also compares references, the same thing == does. So the .equals call still behaves like == until Student overrides it.
Solution
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student other = (Student) o;
return id == other.id;
}
@Override
public int hashCode() {
return Integer.hashCode(id);
}
The parameter of equals has to be Object, matching Object’s signature exactly, or this would be a new overload rather than an override, and code that calls .equals through an Object reference would still get the inherited version. hashCode is built from the same field equals uses, id. So two equal students, as equals defines it, always return the same hash code. That is the rule Java requires between the two methods.