ArrayList.contains()vs HashMap.containsKey()vs HashMap.get()

Ada*_*hns 6 java arraylist hashmap

是否ArrayList.contains()必须迭代所有项目才能进行检查?有HashMap.containsKey()吗?我知道HashMap.get()不需要,但这就是为什么它是最有效的?

can*_*nge 17

ArrayList.contains()迭代?

/**
 * Returns <tt>true</tt> if this list contains the specified element.
 * More formally, returns <tt>true</tt> if and only if this list contains
 * at least one element <tt>e</tt> such that
 * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
 *
 * @param o element whose presence in this list is to be tested
 * @return <tt>true</tt> if this list contains the specified element
 */
public boolean contains(Object o) {
    return indexOf(o) >= 0;
}

/**
 * Returns the index of the first occurrence of the specified element
 * in this list, or -1 if this list does not contain the element.
 * More formally, returns the lowest index <tt>i</tt> such that
 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
 * or -1 if there is no such index.
 */
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;
}
Run Code Online (Sandbox Code Playgroud)

为什么是.是的,它确实.


HashMap.containsKey()是否会迭代?

/**
 * Returns <tt>true</tt> if this map contains a mapping for the
 * specified key.
 *
 * @param   key   The key whose presence in this map is to be tested
 * @return <tt>true</tt> if this map contains a mapping for the specified
 * key.
 */
public boolean containsKey(Object key) {
    return getEntry(key) != null;
}

/**
 * Returns the entry associated with the specified key in the
 * HashMap.  Returns null if the HashMap contains no mapping
 * for the key.
 */
final Entry<K,V> getEntry(Object key) {
    if (size == 0) {
        return null;
    }

    int hash = (key == null) ? 0 : hash(key);
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
         e != null;
         e = e.next) {
        Object k;
        if (e.hash == hash &&
            ((k = e.key) == key || (key != null && key.equals(k))))
            return e;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

不,通常不是.的种类?也许?如果真的有吗?

除了开玩笑,如果你想要查找速度,这就是你找到它的地方.只有迭代才能处理非常罕见的哈希冲突.如果你想在这里解释一下.


Java 8更新:

在java 8中,ArrayList.contains() ...是相同的.打哈欠.

但是HashMap.containsKey()现在使用getNode().漂亮.

/**
 * Returns <tt>true</tt> if this map contains a mapping for the
 * specified key.
 *
 * @param   key   The key whose presence in this map is to be tested
 * @return <tt>true</tt> if this map contains a mapping for the specified
 * key.
 */
public boolean containsKey(Object key) {
    return getNode(hash(key), key) != null;
}

/**
 * Implements Map.get and related methods
 *
 * @param hash hash for key
 * @param key the key
 * @return the node, or null if none
 */
final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

它仍然会偶尔迭代,因为while循环会告诉你.但是,这种情况很少见.

我想给有关效率的细节,但已经有一个答案在这里.


HashMap.containsKey()vs HashMap.get()

由于这些都将他们的大部分工作委托给相同的方法(7中的genEntry()和8中的getNode())我认为你不会发现它们之间存在太大的性能差异.他们的迭代行为将是相同的.

如果您喜欢编译的java文档,而不是点击而不是搜索,那么试试这个.