java中所有集合后面使用的数据结构

问题描述 投票:1回答:2

最近我被面试官询问时,他要求我在java中提供所有馆藏背后的数据结构,例如ArrayList,Map等。这些数据结构本身不是吗?如果没有,那么哪些数据结构支持它们?

java data-structures collections
2个回答
1
投票

ArrayList的底层数据结构是Array,LinkedList是Link对象,HashMap是LinkedList或Tree的Array。希望这可以帮助。


0
投票

由于源提供了所有的实现细节,我只是暴露了一堆最常用的collections


  • java.util.ArrayList<E>

ArrayList的实施内部回落到arrayObject

/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer. Any
 * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
 * will be expanded to DEFAULT_CAPACITY when the first element is added.
 */
transient Object[] elementData; // non-private to simplify nested class access

由于arrays有固定的大小,ArrayList在每个add调用,如果需要elementData通过本地调用System::arrayCopy重新创建。


  • java.util.LinkedList<E>

LinkedLists在对象引用而不是arrays上工作。所有项目E都存储在内部class Node<E>的实例中:

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

每个Node保持指向其下一个和前一个兄弟姐妹的指针。

LinkedList将仅保留对其第一个和最后一个元素的引用,不支持ergo随机访问:

/**
 * Pointer to first node.
 * Invariant: (first == null && last == null) ||
 *            (first.prev == null && first.item != null)
 */
transient Node<E> first;

/**
 * Pointer to last node.
 * Invariant: (first == null && last == null) ||
 *            (last.next == null && last.item != null)
 */
transient Node<E> last;

  • java.util.HashMap<K,V>

它们将键和值存储到内部包类Node<K,V> extends Map.Entry<K,V>中。

节点通过函数调用HashMap::putVal存储到节点array中:

/**
 * The table, initialized on first use, and resized as
 * necessary. When allocated, length is always a power of two.
 * (We also tolerate length zero in some operations to allow
 * bootstrapping mechanics that are currently not needed.)
 */
transient Node<K,V>[] table;

此外,Hashmaps使用EntrySet extends AbstractSet<Map.Entry<K,V>>系列,不断反映table中的元素。

/**
 * Holds cached entrySet(). Note that AbstractMap fields are used
 * for keySet() and values().
 */
transient Set<Map.Entry<K,V>> entrySet;

然后entrySet作为可迭代的collection暴露:

for ( Map.Entry<String, Integer> entry : this.myMap.entrySet() ) { /* ... */ }

  • java.util.HashSet<E>

有趣的是HashSet<T>使用HashMap<T, Object>,正如我们所见,再次由java.util.Set<T>支持。

private transient HashMap<E,Object> map;

你会看到HashSet的身体与其他java数据结构相比有限,因为它的大多数操作只是其内部HashMap结构的后备。

E.g:

HashSet::add

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

HashSet::iterator

public Iterator<E> iterator() {
    return map.keySet().iterator();
}
© www.soinside.com 2019 - 2024. All rights reserved.