jdk集合类

jdk集合类

一、简介

集合类是java开发的基础。在此进行整体框架性的介绍。

二、集合接口

集合类主要分为两大集合接口,分别是Collection接口和Map接口。

  1. Collection接口下,主要有List(列表)、Set(集合)、Queue(队列)

  2. Map接口,下面就是Map(hash),也就是键值对相关的集合。

三、集合实现

集合类底层存储实现主要有两种,分别是数组和链表。

3.1 数组实现

典型数组实现有ArrayList和HashMap,有默认初始值的。

3.1.1 ArrayList

ArrayList的初始值是10,当然也可以指定初始值,源码为:

private static final int DEFAULT_CAPACITY = 10;
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

数组的增加方式是在原长度的基础上增加0.5倍,也就是变为原来的1.5倍,源码如:

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    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);
}

触发数组增加的时机,是在列表添加新元素时判断的,通常当前容量加1,再与数组容量比,如果小了,则表示需要扩容了,源码为:

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    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);
}
3.1.2 HashMap

HashMap的数组初始值是16,源码为:

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

数组增长的因子是0.75,源码为:

static final float DEFAULT_LOAD_FACTOR = 0.75f;

数组增加阈值是capacity * load factor,原码为:

/**
 * The next size value at which to resize (capacity * load factor).
 * @serial
 */
// If table == EMPTY_TABLE then this is the initial capacity at which the
// table will be created when inflated.
int threshold;

增长值为,2的位数且最小的,大于原容量的,原码为:

private void inflateTable(int toSize) {
    // Find a power of 2 >= toSize
    int capacity = roundUpToPowerOf2(toSize);

    threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
    table = new Entry[capacity];
    initHashSeedAsNeeded(capacity);
}

增长触发点仍然是进行数据插入时。

其它集合实现类的数组实现方式,在此不细说。

3.2 链表实现

对于链接,是没有所谓初始值的,直接在链表头或链表尾添加,在此不细说。

四、集合java包

集合类主要集中在java.util包和java.util.concurrent包下。

4.1 java.util包

对于java.util包下的集合类,分为线程安全和非安全,线程安全的实现方式是在方法上加synchroniced关键字,控制粒度比较粗。

4.2 java.util.concurrent包

对于java.util.concurrent包下的集合类,里面的实现类是安全的,实现方式是通过lock锁,这种实现方式,控制粒度比较细,效率更高。而且像ConcurrentHashMap类,还对数据进行分段,锁也是加在各个分段上,因此效率更高。另外在有序集合上,还加入了SkipList(跳表)这种数据结构,进行快速查询,如ConcurrentSkipListMap,CurrentSkipListSet。

五、集合类图

5.1 java.util包下的类图

img

5.2 java.util.concurrent包下的类图

img

发布了274 篇原创文章 · 获赞 95 · 访问量 50万+

猜你喜欢

转载自blog.csdn.net/chinabestchina/article/details/105188004