java集合介绍,线程安全、效率、扩容机制、底层实现

264 阅读1分钟

image.png

  • ArrayList:Object[] 数组,线程不安全,适用于频繁查找,动态扩容

    • 扩容源码
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1); // 新的容量, *= 1.5
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity); // 复制
    }
        
    

    检查是否需要扩容—>扩容—>内容copy

  • Vector:Object[] 数组,线程安全

  • LinkedList:双向链表,线程不安全

  • HashSet:无序、唯一,基于HashMap实现,底层采用HashMap实现

  • LinkedHashSet:HashSet的子类

  • LinkedHashMap:基于HashMap

  • TreeSet:基于红黑树

  • HashMap:数组+链表,线程不安全,扩容为2的n次方

    • 1.8之后为数组+红黑树,当8 < 链表长度 < 64时,先扩容再转换为红黑树
    • 并发下由于rehash会导致元素之间形成循环;并发下存在数据丢失;推荐使用ConcurrentHashMap
  • LinkedHashMap:基于HashMap

  • HashTable:数组+链表,线程安全,基本被淘汰,不建议使用

  • TreeMap:红黑树

  • ConcurrentHashMap:数组+链表/红黑树,线程安全

ConccurrentHashMap与HashTable线程安全比较

&bnsp;ConccurrentHashMapHashTable
效率
底层jdk1.7:分段数组+链表数组+链表
底层1.8数组+链表/红黑树数组+链表
线程安全方式jdk1.7分段锁synchronized
线程安全方式1.8synchronized + CASsynchronized

image.png

image.png

image.png 链表长度超过 8 时,转换为红黑树,加快查询效率。synchronized只锁住当前链表/红黑树的根节点。