一、List
1.List集合特有功能
/*
* List集合的特有功能:
* A:添加功能
* void add(int index,Object element):在指定位置添加元素
* B:获取功能
* Object get(int index):获取指定位置的元素
* C:列表迭代器
* ListIterator listIterator():List集合特有的迭代器
* D:删除功能
* Object remove(int index):根据索引删除元素,返回被删除的元素
* E:修改功能
* Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
*/
测试类
@Test
public void testList(){ List list = new ArrayList();
list.add("AAA");
list.add("BBB");
list.add("CCC");
list.add("DDD");
System.out.println(list); //1.在指定索引位置添加元素
list.add(1,"QQQ");
System.out.println(list); //2.获取指定索引位置的元素
String str = (String)list.get(1);
System.out.println("索引为1的元素: " + str); //3.移除指定索引位置的元素
list.remove(1);
System.out.println(list); //4.修改指定索引位置的元素
list.set(0,"KKK");
System.out.println(list); //5.列表迭代器
ListIterator it = list.listIterator();
while(it.hasNext()){
String s = (String)it.next();
System.out.print(s + " ");
} System.out.println(""); //可以逆向遍历,但是必须先正向遍历,没意义
while(it.hasPrevious()){
String s = (String)it.previous();
System.out.print(s + " ");
} }
结果:
[AAA, BBB, CCC, DDD]
[AAA, QQQ, BBB, CCC, DDD]
索引为1的元素: QQQ
[AAA, BBB, CCC, DDD]
[KKK, BBB, CCC, DDD]
KKK BBB CCC DDD
DDD CCC BBB KKK
2.List子类的特点
ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
二、ArrayList
1.ArrayList简介
ArrayList是一个动态数组,它的容量能动态的增长。
它继承于AbstractList,实现了List、RandomAccess、Cloneable、Serializable这些接口。
(1)ArrayList继承于AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历功能。
(2)ArrayList实现了RandomAccess接口,及提供了随机访问功能。在ArrayList中,我们可以通过元素的序列号快速获取元素对象,这就是快速随机访问。
(3)ArrayList实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
(4)ArrayList实现了Serializable接口,意味着ArrayList支持序列化,能够通过序列化去传输。
ArrayList不是线程安全的,只能用在单线程环境下,多线程下可以考虑Collections.synchronizedList(List list)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。
2.私有属性
ArrayList定义只定义了两个私有的属性。
/*
* 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; /*
* The size of the ArrayList (the number of elements it contains).
*/
private int size;
elementData: 是Object[]类型的数组,它保存了添加到ArrayList中的元素。实际上,elementData是动态数组,我们能通过ArrayList(int initialCapacity)来执行他的初始容量为initialCapacity。如果通过无参的构造函数ArrrayList()来创建ArrayList,则elementData的容量默认是10。elementData数组的大小会根据ArrayList容量的增长而动态增长。
size: 是动态数组的实际大小。
关键字: transient
一个对象只要实现了Serilizable接口,这个对象就可以被序列化,Java的这种序列化模式为开发者提供了很多便利,可以不必关心具体的序列化过程,只要这个类实现了Serilizable接口,这个的所有属性和方法都会自动序列化。但是有种情况是有些属性不需要序列化的,所以就用到了这个关键字。只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化指定的目的地中。
3.构造函数
ArrayList提供了三种构造函数。
//ArrayList无参构造函数。默认容量是10
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
} //ArrayList带容量大小的构造函数。
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);
}
} //创建一个包含collection的ArrayList
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
this.elementData = EMPTY_ELEMENTDATA;
}
}
4.ArrauList遍历方式
ArrayList支持3种遍历方式。
(1)随机访问,通过索引值去遍历。
String s; for(int i = 0;i < list.size();i++){
s = list.get(i);
}
(2)增强for循环
String s;
for(String str : list){
s = str;
}
(3)Iterator循环
String s;
Iterator<String> it = list.iterator();
while(it.hasNext()){
s = it.next();
}
5.总结
(1) ArrayList 实际上是通过一个数组去保存数据的。当我们构造ArrayList时,若使用默认构造函数,则ArrayList的默认容量大小是10。
(2) 当ArrayList容量不足以容纳全部元素时,ArrayList会重新设置容量
int newCapacity = oldCapacity + (oldCapacity >> 1);
即新容量是旧容量的1.5倍。