Reputation: 29
The Remove statement is not removing the object. I can see the list size as 2 before & after remove statement.
public class Test {
private static class Point {
private int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(final String[] args) {
List<Point> pList = new ArrayList<>();
pList.add(new Point(1, 2));
pList.add(new Point(3, 4));
System.out.println(pList.size());
pList.remove(new Point(3, 4));
}
}
Upvotes: 1
Views: 316
Reputation: 9
Refer to https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#remove(java.lang.Object) for the expected behavior of ArrayList.remove(). The two incarnations of "new Point(3, 4)" create different objects on the heap so they have different references, and since the Point class does not override the equals method, the comparison does not find a match.
The remove method will have the behavior you expect if either you have
Point p = new Point(3, 4);
pList.add(p);
pList.remove(p);
or you override the equals method in the class Point with something like:
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (this == other) return true;
if (!(other instanceof Point)) return false;
Point otherPoint = (Point) other;
return x == otherPoint.x && y == otherPoint.y;
}
See also: https://www.geeksforgeeks.org/equals-hashcode-methods-java/
Upvotes: 0
Reputation: 7290
Although technically your question already has correct answers, I'd like to add some explanation.
Your program creates three Point
instances (using new Point(...)
) in the following lines:
public static void main(final String[] args) {
List<Point> pList = new ArrayList<>();
pList.add(new Point(1, 2)); // <-- Here is the first one
pList.add(new Point(3, 4)); // <-- Here is the second one
System.out.println(pList.size());
pList.remove(new Point(3, 4)); // <-- Here is the third one
System.out.println(pList.size());
}
The second and third happen to have the same x
and y
values, but that isn't enough for Java's library functions to understand that they are equal in whatever sense. Per se, two instances are only equal if they are actually two references to the very same instance (e.g. if you saved your second Point
to a local variable and used that for the removal).
With your code, trying to remove the third Point
finds out that (exactly) this Point
isn't on the list, and does nothing.
But you can write an equals()
method in your Point
class where you define, under which circumstances you want two different Point
s to be regarded as equal. You'd typically have this method compare x
and y
.
Examples can be seen in other answers. Or, if you use an IDE like Eclipse, you'll find a function named "create hashCode() and equals()" that writes a perfect equals()
method for you, including all the corner cases that one might casually forget to cover.
WTF is hashCode()
? To support different data structures besides ArrayList
(e.g. HashMap
), a specific equals()
method should always be accompanied by a matching hashCode()
method.
Upvotes: 0
Reputation: 3207
You need to override both equals
and hashcode
methods.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
Upvotes: 0
Reputation: 889
As @sam points out, here's an example with hashCode and equals:
public class Test {
private static class Point {
private int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
return x * y;
}
@Override
public boolean equals(Object o) {
if (o instanceof Point) {
Point p = (Point) o;
return p.x == x && p.y == y;
}
return false;
}
}
public static void main(final String[] args) {
List<Point> pList = new ArrayList<>();
pList.add(new Point(1, 2));
pList.add(new Point(3, 4));
System.out.println(pList.size());
pList.remove(new Point(3, 4));
System.out.println(pList.size());
}
}
Upvotes: 1
Reputation: 8898
You Point
class does not override the equals
method, which the remove
method will use to determine whether or not the item is in the list. If you save your new Point(3,4)
value into a local variable it will be removed because it is identity equal. Or you can override equals
and hashcode
.
Upvotes: 8