为自定义对象列表实现removeAll时出现问题

发布于 2024-08-28 10:02:38 字数 1466 浏览 10 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不疑不惑不回忆 2024-09-04 10:03:06

我发现他原来的说法是真的。仅当您覆盖迭代器中的删除时,removeAll 才会自动工作。仅仅覆盖 Collection 中的删除是不够的,因为removeAll(以及clear和retainAll)都使用迭代器来工作。由于除了迭代器中的remove之外,在使用迭代器时不应更改底层集合,因此如果不重写迭代器中的remove,则removeAll、clear和retainAll将不起作用。如果您在迭代器内的删除方法中抛出 UnsupportedOperationException,那么您在调用所讨论的三个方法之一时将看到该异常。

I have found that his original statement it true. removeAll works automatically only if you override the remove in the iterator. Just overriding the remove in the Collection is not enough because the removeAll (and clear and retainAll) all use the iterator to work. Since you should not change the underlying collection while using the iterator except for the remove in the iterator, if you do not override the remove in the iterator, the removeAll, clear and retainAll will not work. If you throw an UnsupportedOperationException in the remove method inside the iterator, that is what you will see if you call one of the three methods discussed.

花开半夏魅人心 2024-09-04 10:03:04

你说:

...由于我的列表是在自定义对象上创建的,因此removeAll 方法对我不起作用。

正如其他人所说, .removeAll() 应该适用于您描述的场景,即使对于自定义对象,只要自定义对象遵守 Java Collections 对其对象期望的约定,包括正确实现 equals() 和 hashCode()方法。

我尝试了各种方法来完成这项工作: - 为包含列表的自定义对象实现了 equals() 和 hashCode - 为自定义对象实现了 Comparable 接口 - 为自定义对象实现了 Comparator 接口 ...

听起来你是尝试不同的方法:编码一种方法,尝试它,快速编码另一种方法,尝试它,编码另一种方法,......值得放慢速度并尝试理解为什么每种方法失败和/或确定为什么该方法会成功。在继续下一个之前,请先尝试适合您的情况。如果您已经调查并确定了每种方法不起作用的原因,请在您的问题中进行解释。如果您还没有,那么让我们通过发布代码来提供帮助。

既然大多数人都同意第一种方法 (.removeall()) 应该有效,并且由于涉及自定义对象,为什么不快速回顾一下这个 StackOverflow 问题,看看是否有什么问题从你身上跳出来:

在 Java 中重写 equals 和 hashCode

“在 Java 类中重写 equals 和 hashCode 时需要考虑哪些问题/陷阱?”

You said:

... Since my List is created on a custom object, the removeAll method won't work for me.

As others have stated, .removeAll() should work for the scenario you described, even for custom objects, as long as the custom objects obey the contracts that Java Collections expects of its objects, including a properly implement equals() and hashCode() method.

I have tried various methods to make this work: - implemented equals() and hashCode for the custom object comprising the list - implemented the Comparable Interface for the custom object - implemented the Comparator Interface for the custom object ...

It sounds like your are shot-gunning different approaches: coding one, trying it, quickly coding another, trying it, coding yet another, ... It make be worthwhile to slow down and try to understand why each approach failed and/or determine why that approach won't work for your situation, before moving on to the next. If you've already investigated and determined why each approach won't work, please explain in your question. If you haven't, then let us help by posting code.

Since most people agree the first approach (.removeall()) should have work and since custom objects are involved, why not take a quick review of this StackOverflow question to see if anything jumps out of you:

Overriding equals and hashCode in Java

"What issues / pitfalls do I need to consider when overriding equals and hashCode in a java class?"

晨光如昨 2024-09-04 10:02:52

重写 equalshashCode 方法足以使方法 removeAll 对自定义对象起作用。

您可能没有以正确的方式覆盖它们。一些代码会对我们有很大帮助。

Overriding equals and hashCode methods is enough to make method removeAll work on custom objects.

It's likely that you didn't override them in a proper way. Some code will help us a lot.

爱的十字路口 2024-09-04 10:02:45

Java 集合已经满足您的场景。调用 Collection.removeAll(Collection) 它将使用 equals() 方法从传入的集合中删除所有项目来测试相等性。

List<String> list1 = new ArrayList<String>();
Collections.addAll(list1, "one", "two", "three", "four");
List<String> list2 = new ArrayList<String>();
Collections.addAll(list2, "three", "four", "five");
list1.removeAll(list2); // now contains "one", "two"

为了使这项工作有效,您存储的对象只需要正确实现 equals/hashCode 契约,即:给定任意两个对象 ab

a.equals(b) == b.equals(a)

并且:

a.hashCode() == b.hashCode() if a.equals(b)

定义不正确equals 和 hashCode 方法会产生未定义的行为,并且是集合相关问题的常见原因。

Java Collections already cater for your scenario. Call Collection.removeAll(Collection) and it'll remove all the items from the passed in collection using the equals() method to test for equality.

List<String> list1 = new ArrayList<String>();
Collections.addAll(list1, "one", "two", "three", "four");
List<String> list2 = new ArrayList<String>();
Collections.addAll(list2, "three", "four", "five");
list1.removeAll(list2); // now contains "one", "two"

To make this work the objects you're storing just need to properly implement the equals/hashCode contract, which is: given any two objects a and b:

a.equals(b) == b.equals(a)

and:

a.hashCode() == b.hashCode() if a.equals(b)

Improperly defined equals and hashCode methods create undefined behaviour and are the common cause of collections related issues.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文