英文:
ArrayList not removing object
问题
Remove语句未能移除该对象。在remove语句之前和之后,我可以看到列表大小为2。
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));
}
}
英文:
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));
}
}
答案1
得分: 8
你的 Point
类没有重写 equals
方法,而 remove
方法将使用该方法来判断项目是否在列表中。如果你将 new Point(3,4)
值保存到一个局部变量中,它将被移除,因为它是身份相等的。或者你可以重写 equals
和 hashcode
方法。
英文:
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
.
答案2
得分: 1
如@sam指出的那样,这里有一个使用hashCode和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());
}
}
英文:
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());
}
}
答案3
得分: 0
你需要重写 equals
和 hashcode
方法。
@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);
}
英文:
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);
}
答案4
得分: 0
请参考 https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#remove(java.lang.Object) 获取ArrayList.remove()的预期行为。两个版本的"new Point(3, 4)"在堆上创建了不同的对象,因此它们具有不同的引用;由于Point类没有覆盖equals方法,比较没有找到匹配。
如果你满足以下条件,remove方法将会有你期望的行为:
Point p = new Point(3, 4);
pList.add(p);
pList.remove(p);
或者你可以通过以下方式覆盖Point类中的equals方法:
@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;
}
另请参考:https://www.geeksforgeeks.org/equals-hashcode-methods-java/
英文:
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/
答案5
得分: 0
虽然从技术上讲,您的问题已经有了正确的答案,但我想补充一些解释。
您的程序在以下几行中创建了三个 Point
实例(使用 new Point(...)
):
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());
}
第二个和第三个实例恰好具有相同的 x
和 y
值,但这对于 Java 的库函数来说还不足以让它们在某种意义上被视为相等。从本质上讲,只有当两个实例实际上是对同一个实例的引用时(例如,如果您将第二个 Point
保存到一个局部变量中,并将其用于删除),它们才是相等的。
使用您的代码,尝试移除第三个 Point
会发现列表中并没有(完全)相同的 Point
,因此不会执行任何操作。
但是您可以在 Point
类中编写一个 equals()
方法,在该方法中定义您希望在什么情况下将两个不同的 Point
视为相等。通常情况下,您可以在该方法中比较 x
和 y
。
示例可以在其他答案中找到。或者,如果您使用诸如 Eclipse 之类的集成开发环境,您会找到一个名为“create hashCode() and equals()”的功能,它会为您编写一个完美的 equals()
方法,包括所有可能会被随意忽略的边界情况。
hashCode()
是什么鬼?为了支持除了 ArrayList
(例如 HashMap
)之外的不同数据结构,特定的 equals()
方法应该总是伴随一个匹配的 hashCode()
方法。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论