繁体   English   中英

集合接口中的 containsall 方法如何在 java 中工作?

[英]how containsall method from collections interface works in java?

如果我有两个来自 Collection 接口的对象列表

清单 1 = {约翰、蒂姆、汤姆}

清单 2 = {约翰,蒂姆}

并且这两个列表都是 ArrayList 的实例

Java 如何通过 list1.containsall(list2) 知道 list2 是否包含在 list1 中?
我知道Java在 containsall() 方法的实现中使用了 contains 方法,而 contains 方法使用了 equal() 方法。 我理解这些差异,但我不确定 Java 如何遍历列表 1 的元素。

因此,如果我使用 list1.containsAll(list2),则 containsAll() 方法是通过一个循环实现的,该循环在这种情况下遍历 list2 的每个对象,如果其中一个元素不在列表 1 中,则抛出 false。

所以我的主要问题是 JAVA 如何知道列表 1 包含所有元素而没有另一个循环来遍历列表 1 的元素? java是在内部完成工作还是什么?

我目前知道要做这样的事情,我必须使用

for (int i = 0; i < list1.size(), i++)

list1.get(i).constainsAll(list2);

,, 考虑到我必须修改 containsAll 的代码才能正常工作并实现 get() 方法,这对我来说似乎更合乎逻辑

也许正式回答这个问题,因为我认为这是一个很好的问题。

containsAll方法遍历提供的集合并在每个条目上执行contains()方法,该方法还遍历正在比较的另一个列表。 请参阅下面的java代码摘录

  public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }

public boolean contains(Object o) {
        Iterator<E> it = iterator();
        if (o==null) {
            while (it.hasNext())
                if (it.next()==null)
                    return true;
        } else {
            while (it.hasNext())
                if (o.equals(it.next()))
                    return true;
        }
        return false;
    }

这使得这个 o(n^2) (如果最后一个值不匹配或列表实际匹配,最坏的情况)(这真的很糟糕,特别是如果你有要比较的大集合)。

更好的方法是执行以下操作:(显然,如果您使用字符串之外的对象或其他集合并执行一些空检查或其他操作,则需要进行调整)

 public boolean containsAllStrings(List<String> list1, List<String> List2) {
        Map<String, String> list1Map = list1.stream().collect(Collectors.toMap(c -> c, c -> c));
        return List2.stream().allMatch(list1Map::containsKey);
    }

这样,它迭代的最大数量为 2n(一个用于将项目添加到地图,一个用于比较)时间(n 是 2 的最大列表)而不是 n^2。

它可能看起来一样,但哈希映射很好,因为它们包含指向内存中值的指针(使用键的哈希值)并且不迭代所有值,使得访问映射中的值总是 o(1) . 这是最佳的。

显然,在内存利用等方法之间存在权衡,但为了速度,这是最好的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM