目录
5.4.3 HashMap,TreeMap, LinkedHashMap区别
一:Iterable接口
定义了迭代集合的迭代方法
Iterator对应方法及其描述
1)hasNext(): 返回迭代器是否有更多元素
2)next返回下一个位置元素
3)remove() : 移除元素
【注意】:每次产生一个迭代器,他总是指向第一个元素的前面位置
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class review01 {
public static void main(String[] args) {
//虽然容量大小定义为2,但是随着元素加入,其容量也自动增长
List<Integer> list1 = new ArrayList<Integer>(2);
System.out.println(list1.size()); // 0
list1.add(3);
list1.add(5);
list1.add(8);
list1.add(1);
Iterator iterator = list1.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next()); // 3 5 8 1
}
}
}
二.Collection接口
定义了集合中通用方法
- size()
- isEmpty()
- contains()
- add()
- addAll()
- remove()
- removeAll()
- toArray()
【注意】:1. collection中是contains(),而map是containsKey()
2.toArray()方法object[] arr = coll.toArray()
三:List接口
1)元素被添加到集合中以后,取出的时候是按照放入顺序的
2)List可以重复
3)存在下表,可以直接依靠下标取值
一些常用方法:
- get()
- set()
- indexOf()
- lastIndexOf()
3.1 ArrayList类
3.1.1 介绍
ArrayList是List接口的可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。
除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。
随着向ArrayList中不断添加元素,其容量也自动增长。自动增长会带来数据向新数组的重新拷贝,
因此,如果可预知数据量的多少,可在构造ArrayList时指定其容量。在添加大量元素前,
应用程序也可以使用ensureCapacity操作来增加ArrayList实例的容量,这可以减少递增式再分配的数量。
3.1.2 底层
1)底层使用的数据结构
ArrayList底层使用可变数组保存元素,其操作基本上是对数组的操作
private transient Object[] elementData;
2)构造方法
提供了三种方式的构造器,可以构造一个默认初始容量为10的空列表,或者构造一个指定初始容量的空列表,
或者构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列。
public ArrayList() {
this(10);
}
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
3)调整数组容量
每当向数组中添加元素时,都要去检查添加后元素的个数是否会超出当前数组的长度,如果超出,
数组将会进行扩容,以满足添加数据的需求。数组扩容通过一个公开的方法ensureCapacity(int minCapacity)来实现。
在实际添加大量元素前,我也可以使用ensureCapacity来手动增加ArrayList实例的容量,以减少递增式再分配的数量。
- 初始容量为10。
- 当数组容量不够是自动扩容为以前的1.5倍
- 数组最大容量为
Integer.MAX_VALUE-8
- ArrayList还给我们提供了将底层数组的容量调整为当前列表保存的实际元素的大小的功能。
它可以通过trimToSize方法来实现。
public void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (size < oldCapacity) {
elementData = Arrays.copyOf(elementData, size);
}
}
3.1.2 线程安全问题
线程不安全
3.2 Vector类
3.2.1 底层实现
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
可以看到vector都增加了syncronized关键字,也就是说,vector的实现与ArrayList类似,但是使用了synchronized进行同步
3.2.2扩容
protected int capacityIncrement;
// 这里是int类型,扩容的时候不是算比例,而是直接跟capacityIncrement相加。
1)vector的构造函数可以传入capacityIncrement参数,它的作用是在扩容数组时,使得数组容量增加
capacityIncreament个。如果这个参数的数值小于等于0,扩容时候每次令capacity为原来的两倍。
2