使用contains或循环列表之间有什么大的区别?

时间:2010-05-21 21:53:47

标签: java list iterator foreach contains

性能方面,使用之间确实存在很大差异:

  • ArrayList.contains(o)vs foreach | iterator
  • LinkedList.contains(o)vs foreach | iterator

当然,对于foreach | iterator循环,我必须明确地比较这些方法并相应地返回true或false。

我正在比较的对象是equals()hashcode()被正确覆盖的对象。

编辑:毕竟不需要知道containsValue,对不起。是的,我很愚蠢...我意识到我的问题是关于containsKey vs foreach是多么愚蠢,没关系,我不知道我在想什么。我基本上想知道上面的内容(编辑出其他内容)。

6 个答案:

答案 0 :(得分:9)

编辑:

随着问题的新形式不再包括HashMap和TreeMap,我的答案完全不同。我现在说没有

我确信其他人已经回答了这个问题,但是在LinkedList和ArrayList中,contains()只调用indexOf(),它遍历集合。

在LinkedList和ArrayList之间以及contains和foreach之间存在微小的性能差异,可能没有任何差异。

答案 1 :(得分:6)

这没有任何差异,因为contains(o)调用indexOf(o),它只是像这样循环:

for (int i = 0; i < size; i++)
    if (o.equals(elementData[i]))
       return i;

(在ArrayList中检查)

答案 2 :(得分:3)

如果没有基准测试,包含在所有情况下应该更快或相同。

对于1和2,它不需要调用迭代器方法。它可以在内部循环。 ArrayList和LinkedList实现都包含indexOf

  1. ArrayList - indexOf是后备阵列上的C风格for循环。
  2. LinkedList - indexOf以C风格循环遍历链接列表。
  3. 对于3和4,您必须区分containsKey和containsValue。

    3。 HashMap,containsKey是O(1)。它通过散列密钥,获取相关的存储桶,然后遍历链表来工作。 containsValue是O(n),只需检查嵌套for循环中每个桶中的每个值即可。

    4。 TreeMap,containsKey是O(log n)。它检查它是否在范围内,然后搜索红黑树。 containsValue,即O(n),使用树的有序遍历。

答案 3 :(得分:2)

ArrayList.contains

return indexOf(o) >= 0;

,其中

public int indexOf(Object o) {
if (o == null) {
    for (int i = 0; i < size; i++)
    if (elementData[i]==null)
        return i;
} else {
    for (int i = 0; i < size; i++)
    if (o.equals(elementData[i]))
        return i;
}
return -1;
}

它与LinkedList类似,只是它使用.next()迭代元素,因此没有太大区别。

public int indexOf(Object o) {
    int index = 0;
    if (o==null) {
        for (Entry e = header.next; e != header; e = e.next) {
            if (e.element==null)
                return index;
            index++;
        }
    } else {
        for (Entry e = header.next; e != header; e = e.next) {
            if (o.equals(e.element))
                return index;
            index++;
        }
    }
    return -1;
}

HashMap.containKey使用密钥的哈希来获取具有该哈希的所有密钥(这很快),然后仅在这些密钥上使用等于,所以那里有一个改进;但containsValue()通过for。

遍历值

TreeMap.containsKey似乎使用比较器进行了明智的搜索,以便更快地找到密钥,因此更好;但containsValue似乎仍然遍历整个三个,直到找到一个值。

总的来说,我认为你应该使用这些方法,因为它们比每次执行循环更容易编写:)。

答案 4 :(得分:0)

我认为使用contains更好,因为通常库实现比手动实现更有效。检查你是否可以在对象构造期间或之后传递一个你编写的比较器方法来处理你的自定义equals和hashcode实现。

谢谢, 克里希纳

答案 5 :(得分:0)

使用foreach / iterator遍历容器总是O(n)时间。 ArrayList / LinkedList搜索也是O(n)。

HashMap.containsKey()是O(1)amortized时间。

TreeMap.containsKey()是O(log n)时间。

对于HashMap和TreeMap,containsValue()是O(n),但可能有针对containsValue()优化的实现与containsKey()一样快。