我是否在 java.util.ArrayList.containsAll 中发现了错误?

发布于 2024-11-02 17:12:20 字数 621 浏览 1 评论 0原文

在 Java 中,我有两个列表:

List<Satellite> sats = new ArrayList<Satellite>();
List<Satellite> sats2 = new ArrayList<Satellite>();

Satellite sat1 = new Satellite();
Satellite sat2 = new Satellite();

sats.add(sat1);

sats2.add(sat1);
sats2.add(sat2);

当我在第一个列表上执行以下 containsAll 方法时:

sats.containsAll(sats2); //Returns TRUE!

它返回 true。但第一个列表 (sats) 仅包含 1 个项目,第二个列表包含 2 个项目。因此,第一个列表 (sats) 甚至不可能包含第二个列表 (sats2) 中的所有项目。知道为什么或者这是 Java JDK 中的一个错误吗?

我在另一个 StackOverflow 问题中读到,这不是执行此类操作的最高效的方法,因此如果有人对如何提高其性能提出建议,那就太好了!

提前致谢!

In Java I've two lists:

List<Satellite> sats = new ArrayList<Satellite>();
List<Satellite> sats2 = new ArrayList<Satellite>();

Satellite sat1 = new Satellite();
Satellite sat2 = new Satellite();

sats.add(sat1);

sats2.add(sat1);
sats2.add(sat2);

When I do the following containsAll method on the first list:

sats.containsAll(sats2); //Returns TRUE!

It returns true. But the first List (sats) only contains 1 item and the second list contains 2. Therefor it's not even possible that the first list (sats) containsAll items from the second list (sats2). Any idea why or is this a bug in the Java JDK?

I've read in another StackOverflow question that this is not the most performant way to do something like this, so if anyone has a suggestion on how to make it more performant that would be great!

Thanks in advance!

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

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

发布评论

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

评论(3

薄凉少年不暖心 2024-11-09 17:12:20

正如 @Progman 所指出的,您可能会覆盖 Satellite 中的 equals 方法。

下面的程序打印 false

import java.util.*;

class Satellite {
}

class Test {
    public static void main(String[] args) {
        List<Satellite> sats = new ArrayList<Satellite>();
        List<Satellite> sats2 = new ArrayList<Satellite>();

        Satellite sat1 = new Satellite();
        Satellite sat2 = new Satellite();

        sats.add(sat1);

        sats2.add(sat1);
        sats2.add(sat2);

        System.out.println(sats.containsAll(sats2));
    }
}

ideone.com demo

我建议你打印这两个列表的内容,检查内容是否对应于什么你期望它是。

As pointed out by @Progman, you're probably overriding the equals method in Satellite.

The program below prints false.

import java.util.*;

class Satellite {
}

class Test {
    public static void main(String[] args) {
        List<Satellite> sats = new ArrayList<Satellite>();
        List<Satellite> sats2 = new ArrayList<Satellite>();

        Satellite sat1 = new Satellite();
        Satellite sat2 = new Satellite();

        sats.add(sat1);

        sats2.add(sat1);
        sats2.add(sat2);

        System.out.println(sats.containsAll(sats2));
    }
}

(ideone.com demo)

I suggest that you print the contents of the two lists and check that the content corresponds to what you expect it to be.

予囚 2024-11-09 17:12:20

对于许多类来说,以相同方式创建的两个对象(例如 new Satellite())将被视为相等是有意义的。请记住,containsAll 并不关心 Collection 包含的对象的副本数量,只关心它至少包含每个不同< /em> 给定的 Collection 中的元素。例如,如果您有一个包含 [A, A]List a 和一个仅包含 [A] 的列表 b ]b.containsAll(a)a.containsAll(b) 都会返回 true。这可能与这里发生的情况类似。

For many classes, it makes sense that two objects created the same way (e.g. new Satellite()) would be considered equal. Keep in mind that containsAll doesn't care about the number of copies of an object that a Collection contains, just that it contains at least one of each distinct element in the Collection that it's given. So for example, if you had a List a that contained [A, A] and a list b that just contained [A], b.containsAll(a) and a.containsAll(b) would both return true. This is probably analogous to what's happening here.

帅气称霸 2024-11-09 17:12:20

回复太晚了,但问题的第二部分 - 更有效的方法 containsAll 是: CollectionUtils.isSubCollection(subSet, superSet)
即 O(n^2) 与 O(n) 复杂度

Too late to reply but the second part of your question - a more efficient way to do containsAll is : CollectionUtils.isSubCollection(subSet, superSet)
That is O(n^2) vs O(n) complexity

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