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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中所有集合后面使用的数据结构相关的知识,希望对你有一定的参考价值。

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

答案

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

另一答案

由于源提供了所有的实现细节,我只是暴露了一堆最常用的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();
}

以上是关于java中所有集合后面使用的数据结构的主要内容,如果未能解决你的问题,请参考以下文章

编写高质量代码:改善Java程序的151个建议(第3章:类对象及方法___建议36~40)

JAVA集合类汇总

java集合类汇总

[ jquery 文档处理 insertBefore(content) before(content|fn) ] 此方法用于把所有匹配的元素插入到另一个指定的元素元素集合的前面,实现外部插入(代码片段

如何使用java将数据从片段传递到android中的另一个片段?

java主要集合类的数据结构