一、List接口
List是一个接口,定义了一组元素是有序的、可重复的集合。通过索引来访问List中的元素。
List 继承自 Collection,较之 Collection,List 还添加了以下操作方法
- 位置相关:List 的元素是有序的,因此有get(index)、set(index,object)、add(index,object)、remove(index) 方法。
- 搜索:indexOf(),lastIndexOf();
- 迭代:使用 Iterator 的功能板迭代器
- 范围性操作:使用 subList 方法对 list 进行任意范围操作。
实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack
二、List的实现类
1.ArrayList
(1)如果在初始化ArrayList的时候没有指定初始化长度,默认长度为10。如果我们明确所插入的元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间,影响效率。
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
}
(2)每次向集合中添加元素时,要做容量检查,当快要溢出时,进行扩容操作,ArrayList扩容ensureCapacity的方案为:
原始容量*3/2+1
/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
(3)ArrayList是线程不安全的,在多线程的情况下不要使用。
如果一定要在多线程使用List,可以使用Vector,因为Vector和ArrayList基本一致,但是Vector是线程安全的,还有就是两者的扩容方案不一致,ArrayList是通过(原始容量*3/2+1)实现的,而Vector是允许设置默认增长长度的,Vector的默认扩容方式为原来的两倍。
(4)ArrayList实现遍历的几种方法
import java.util.*;
public class Test{
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("HAHAHAHA");
//第一种遍历方法使用foreach遍历List
for (String str : list) { //也可以改写for(int i=0;i<list.size();i++)这种形式
System.out.println(str);
}
//第二种遍历,把链表变为数组相关的内容进行遍历
String[] strArray=new String[list.size()];
list.toArray(strArray);
for(int i=0;i<strArray.length;i++) //这里也可以改写为 foreach(String str:strArray)这种形式
{
System.out.println(strArray[i]);
}
//第三种遍历 使用迭代器进行相关遍历
Iterator<String> ite=list.iterator();
while(ite.hasNext())//判断下一个元素之后有值
{
System.out.println(ite.next());
}
}
}
ArrayList如下特点:
- 容量不固定,可以动态扩容
- 有序(基于数组实现,查找快,增删慢)
- 元素可以为null
- 效率高
- 占用空间少,相比LinkedList,不用额外空间维护表结构
2.LinkedList
3.ArrayList和LinkedList的区别
(1)当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是链表的数据结构,需要移动指针。
(2)当对数据进行增删操作是,LinkedList比ArrayList的效率更高,因为ArrayList的实现基于数组,进行增删操作需要移动元素。
(3)ArrayList基于数组数据结构,LinkedList基于链表数据结构。
4.Vector(已过时)
与ArrayList大同小异,主要是Vector是线程安全的。如果考虑线程安全,可以使用Vector。
与ArrayList的区别:
(1)Vector是线程安全的,ArrayList则不是。
(2)Vector默认扩容是原来的两倍,ArrayList是原来的1.5倍(原来容量*3/2+1)。
(3)Vector多了一种迭代器Enumeration。
5.Stack
Stack继承Vector,也是一个线程安全的集合。
Stack也是基于数组实现的。
Stack实现的是栈结构集合。