一、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倍。