Java集合List
List集合代表一个有序、可重复的集合.本质是顺序表,提供增删改查数据的基本功能,且可以通过索引来插入替换和删除集合元素的方法。
List继承体系
Iterable–>Collection–>List–>AbstractCollection–>AbstractList–>ArrayList;
Iterable–>Collection–>List–>AbstractCollection–>AbstractList–>Vector;
Iterable–>Collection–>List–>AbstractCollection–>AbstractList–>Vector–>Stack;
Iterable–>Collection–>List–>AbstractCollection–>AbstractList–>AbstractSequentialList–>LinkedList
AbstractCollection重写了toString()方法,返回“[元素,元素,元素]”
ArrayList
ArrayList是基于数组实现的List类,其封装了一个动态的允许再分配的Object数组,这个数组默认大小是10.当向这个数组添加元素超过了这个数组的大小时,这个数组的长度会自动增加。线程不安全的。
- ensureCapacity(int minCapacity),可以一次性增加一定数量的大小,减少分配次数,从而提高性能,用于确定要保存的数据的数量。
- trimToSize()将Object[]数组的数组长度调整为当前元素的的个数,减少ArrayList对象占用的内存空间。
插入,删除,修改,查找,获取操作如下:
- 插入操作需要先检查是否需要扩容数组,如果数据是插入到尾部的则可直接赋值,否则插入到中部则需要调用System.arraycopy()方法(JNI方法)移动数据腾出空间,再插入数据。
- 删除操作直接通过System.arraycopy()操作覆盖目标值的位置
- 修改元素值只需要在数组中直接替换。
- 查找操作是简单的遍历查找,因此效率可能不高 。但是比LinkedList的遍历速度快。
- 获取元素操作通过index直接返回,比较高效。
Vector
用法上几乎和ArrayList完全相同,但Vector是线程安全的,因此性能比ArrayList低。
Stack
Vector的子类,表示后进先出(LIFO)对象堆栈。
- peek():返回栈的第一个元素,不将该元素移出栈(即取出栈顶元素,也是返回数组末尾的元素);
- pop():返回栈的第一个元素,并将该元素移出栈(即,取出栈顶元素,并将该元素从栈中删除,也是取出数组末尾的元素,然后将该元素从数组中删除);
- push():将一个元素放入栈中,这个栈位于栈顶(通过将元素追加到数组的末尾中)。
LinkedList,底层数据结构是链表,查询慢,增删快,线程不安全,效率高
- 实现了List接口,能对它进行队列操作;
- 实现了Deque接口,即能将LinkedList当作双端队列使用;
- 由于是基于列表的,LinkedList的没有扩容方法!默认加入元素是尾部自动扩容!
public static void main(String[] args){
LinkedList<String> linkedList= (LinkedList<String>) CollTools.getCollections(LinkedList.class);
System.out.println("==================================================================================");
System.out.println("原集合:"+linkedList);
//在队列尾部添加一个元素
linkedList.add("add添加");
System.out.println("add添加后集合:"+linkedList);
//在队列头添加
linkedList.addFirst("addFirst在队列头添加");
System.out.println("addFirst添加后集合:"+linkedList);
//在队列尾部添加一个元素,与add方法等效
linkedList.addLast("addLast添加");
System.out.println("addLast添加后集合:"+linkedList);
String strGetFirst=linkedList.getFirst();
System.out.println("getFirst:"+strGetFirst);
String strLast=linkedList.getLast();
System.out.println("getLast:"+strLast);
System.out.println("==================================================================================");
//在队列尾部添加一个元素,与add方法等效
linkedList.offer("offer在队列尾添加");
System.out.println("offer在队列尾添加后集合:"+linkedList);
linkedList.offerFirst("offerFirst在队列头添加");
System.out.println("offerFirst在队列头添加后集合:"+linkedList);
linkedList.offerLast("offerLast在队列尾部添加");
System.out.println("offerLast在队列尾部添加后集合:"+linkedList);
//与addFirst等效
linkedList.push("push在头部添加元素");
System.out.println("push在头部添加元素后集合:"+linkedList);
//与removeFirst(),remove(),pollFirst(),poll()等效
String strPop=linkedList.poll();
System.out.println("pop返回头部元素并删除这个元素:"+strPop);
System.out.println("pop后集合:"+linkedList);
//与peekFirst()等效
String strPeek=linkedList.peek();
System.out.println("peek获得的元素:"+strPeek);
System.out.println("peek后集合:"+linkedList);
String strElement=linkedList.element();
System.out.println("element获取队列头的元素:"+strElement);
System.out.println("element后集合:"+linkedList);
System.out.println("=================================================================");
String strPeekLast=linkedList.peekLast();//获取队列尾的元素,与getLast()等效
System.out.println("peekLast获取队列尾的元素:"+strPeekLast);
System.out.println("peekLast后集合:"+linkedList);
//获取队列尾的元素,并将此元素移出这个队列,与removeLast()等效
String strPollLast=linkedList.pollLast();
System.out.println("pollLast获取队列尾的元素,并将此元素移出这个队列:"+strPollLast);
System.out.println("pollLast后集合:"+linkedList);
}
应用场景
ArrayList读取速度快于LinkedList,而插入和删除速度又慢于LinkedList。
1.ArrayList随机读取的时候采用的是get(index),根据指定位置读取元素,而LinkedList则采用size/2 ,二分法去加速一次读取元素!
2.ArrayList插入时候要判断容量,删除时候要将数组移位,有一个复制操作!而LinkedList直接插入,不用判断容量,删除的时候也是直接删除跳转指针节点,没有复制的操作!