List接口介绍
List是一种有序的列表(也称为序列 ),用户可以精确控制列表中每个元素的插入位置。 用户可以通过整数索引(列表中的位置)访问列表中的元素,并搜索列表中的元素。
与集合不同,列表允许重复的元素,并且通常允许多个空元素。
该List接口放置额外的约定,超过在Collection指定接口上的iterator,add,remove,equals和hashCode方法合同。 其他继承方法的声明也包括在这里以方便。
常见的List接口实现类
1. ArrayList
可调整大小的List接口的实现。 实现所有可选列表操作,并允许所有元素,包括null 。 除了实现List 接口之外,该类还提供了一些方法来操纵内部使用的存储列表的大小。
每个ArrayList实例都有一个容量 。 容量是用于存储列表中的元素的数组的大小。 它总是至少与列表大小一样大。 当元素添加到当前容量的最大时时,其容量会自动增长。 但是并不像HashMap类似,ArrayList没有规定具体的增长的细节
请注意,此类并不是线程安全的。 如果多个线程同时访问实例,并且至少有一个线程在结构上修改列表,则必须在外部进行同步。:
List list = Collections.synchronizedList(new ArrayList(…));
该类iterator方法返回的迭代器是故障快速的 :如果集合在迭代器创建之后的任何时间内被修改,除了通过迭代器自己的remove和add方法之外,迭代器会抛出一个ConcurrentModificationException 。
可以参考:解读阿里巴巴Java手册:为什么在foreach中禁止add/remove操作
2. CopyOnWriteArrayList
CopyOnWriteArrayList是一个线程安全的变体ArrayList ,其中所有可变操作( add , set ,等等)都是通过对底层数组的最新副本来实现。允许所有元素,包括null 。
CopyOnWriteArrayList操作的成本太高,但是在遍历操作的数量远远超过变化操作(add remove等)的情况下,它可能比其他方法更有效,并且在您无法或不想同步遍历而又需要防止并发线程之间的干扰时很有用。
3. LinkedList
双链表实现了List和Deque接口。 实现所有可选列表操作,并允许所有元素(包括null )。
对双链表执行的所有操作都与预期的一样。索引到列表中的操作将从列表的开始或结束(以更接近指定索引的为准)遍历该列表
请注意,此类不是线程安全的。 如果多个线程同时访问链接列表,并且至少有一个线程在结构上修改列表,则必须在外部进行同步:
List list = Collections.synchronizedList(new LinkedList(…));
这个类的iterator和listIterator方法返回的迭代器是快速故障的 :如果列表在迭代器创建之后的任何时间被结构化地修改,除了通过迭代器自己的remove或add方法之外,迭代器将会抛出一个ConcurrentModificationException 。
4. Stack
Stack类是先进先出(LIFO)堆栈的对象。 它允许一个向量被视为堆栈。 包括push压栈和pop出栈操作,以及查看堆栈顶部的peek,以测试堆栈是否为empty的方法,以及获取对象最靠近堆栈顶部的距离的search方法。
当首次创建堆栈时,它不包含任何项目。
public static void main(String[] args) {
Stack<Integer> stack = new Stack<Integer>();
System.out.println(stack.empty()); //true
stack.push(2);//先入后出,2在最下面
stack.push(1);// 1在2的上面
stack.push(3);//3在1的上面
stack.push(4);//4在3的上面
System.out.println(stack.search(2)); //2距离栈顶为4
}
Deque接口及其实现类提供了更完整和一致的LIFO堆栈操作集,这些接口应优先于此类。 例如:Deque stack = new ArrayDeque();