ArrayList的底层数据结构是一个object类型的数组。
如果不指定初始容量的话,默认为长度为10的空数组。

答:
1、确保arraylist容量满足大小:ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
1.1 计算所需最小容量minCapacity:当到达最大容量后,更新为最新最小所需容量
1.2 确保容量满足所需大小:如果当前所需最小容量比当前元素总数多,那么需要扩容
1.2.1 新容量为原容量的1.5倍:newCapacity = oldCapacity + (oldCapacity >> 1);
1.2.2 通过Arrays.copyOf复制原数组:
elementData = Arrays.copyOf(elementData, newCapacity);
2、数组添加新元素:elementData[size++] = e;


arraylist不是线程安全的。
1)使用Vector替代
2)使用Collections包装:Collections.synchronizedList(new ArrayList<>())
3)使用CopyOnWriteArrayList替代
由于ArrayList使用add方法时,会频繁调用System的arraycopy方法进行扩容,因此如果该list是以查询为主的话,使用ArrayList;
如果增删多的话,就不适合使用arrayList了,此时就可以使用LinkedList了,因为它的增删操作的时间复杂度为O(1),而ArrayList的时间复杂度为O(n),n为ArrayList的长度。
jdk1.8之后,HashMap采用:数组 + 链表/红黑树 的方式来存储数据。
HashMap的底层数据结构是node类型的数组:transient Node默认初始容量大小为16,默认扩容因子是0.75。


计算该key所在数组的位置主要有3个步骤:
说明:
1)为什么要将hashcode右移16位再进行异或运算?
这样做的好处是,可以将hashcode高位和低位的值进行混合做异或运算。这样,低位的信息中加入了高位的信息,等于说计算下标时把hash的高16位也参与进来了,掺杂的元素多了,那么生成的hash值的随机性会增大,减少了hash碰撞。
2)为什么HashMap的长度一般是2^n?
当length总是2的n次方时,h& (length-1)运算等价于对length取模,也就是h%length,但是&比%具有更高的效率。

HashMap的添加元素的过程:
大于8则可能转成红黑树(要求数组同时需要大于64),满足则在红黑树中插入节点;否则在链表中插入;在遍历链表的过程中如果存在key的hashcode&equals相等则替换即可
1)使用HashTable替代
2)使用Collections包装:Collections.synchronizedMap(new HashMap
3)使用ConcurrentHashMap替代