1.深入理解java集合List
2016-05-03 19:06
645 查看
下图是java集合框架图,Collection、Map是集合框架的顶级类,Iterator是集合迭代器。
Collection介绍(主要讲解实现类,主要特点,适用场景,实现原理)
1、List接口,主要实现类Vector、ArrayList、LinkedList
(1)Vector ,如下图源码结构,可以看出Vector主要有3个成员变量,elementData是Vector
保存数据的数组成员,elementCount:记录Vector 当前容量,capacityIncrement扩容增量
特点原理: Vector 底层是使用数组保存元素,因此随机访问非常迅速,但随机插入和删除元素却要移动元素,Vector
使用本地方法System.arraycopy移动数组元素,新增元素时如果当前数组空间不足,则自动扩容以保证足够的空间存储元素,Vector每个操作方法都指定了synchronized关键字,因此Vector的操作时线程安全的。
适用场景:Vector
的适用于读多写少,线程安全的业务场景。
(2)ArrayList,ArrayList和Vector非常相似,区别仅仅是ArrayList操作方法不是线程安全的,要把非线程安全的arraylist转变线程安全可以使用Collections.synchronizedList方法
适用场景:ArrayList的适用于读多写少,线程非安全的业务场景。
(3)LinkedList,List的链表实现,如下图源码结构,可以看出LinkedList主要有3个成员变量,size:链表大小,first:是链表开始节点,last:是链表尾部节点。
那LinkedList元素保存在那里呢?内部使用静态内部类Node<E>来保存数组元素,看下面代码:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
通过代码可以看到,LinkedList节点类Node<E>包含了元素E,以及节点的前一个和后一个元素的引用。下面我们看看LinkedList读取,新增,删除元素时的操作
(1)读取一个元素,当读取第一个和最后一个元素时,直接返回first,last节点的成员变量E的值即可,当随机获取一个元素时,LinkedList通过 Node<E> node(int index){}方法找到指定位置index元素节点,
具体实现代码如下:
Node<E> node(int index) {
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
可以看到LinkedList查找元素必须遍历节点元素,当index < (size >> 1)也就是size/2时,从first开始遍历,否则从last遍历,这样一定程度上可以减少遍历次数。
(2)新增元素,当新增到链表头和链表尾时,直接改变元素前后指针即可,当随机添加元素到任意位置时,代码如下:
public void add(int index, E element) {
checkPositionIndex(index); //检查index是否合法
//判断index是否在链表尾
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));//node()方法定位index元素位置,找到index位置元素,添加新的元素
}
LinkedList随机新增元素也是要遍历链表,当链表较大时性能比较差。
(3)删除元素,同样当删除链表头和链表尾时,直接改变元素前后指针即可,当随机删除元素到任意位置时,代码如下:
public E remove(int index) {
checkElementIndex(index);//检查index是否合法
return unlink(node(index));//node()方法定位index元素位置,找到index位置元素,删除元素
}
特点原理:集合元素无上限,集合使用Node<E>类保存元素E,读取,新增,删除链表头和尾效率非常快。随机读取,新增,删除链表头和尾效率较差!
适用场景:顺序读取,新增,删除场景,不适合随机读写,线程不安全。
Collection介绍(主要讲解实现类,主要特点,适用场景,实现原理)
1、List接口,主要实现类Vector、ArrayList、LinkedList
(1)Vector ,如下图源码结构,可以看出Vector主要有3个成员变量,elementData是Vector
保存数据的数组成员,elementCount:记录Vector 当前容量,capacityIncrement扩容增量
特点原理: Vector 底层是使用数组保存元素,因此随机访问非常迅速,但随机插入和删除元素却要移动元素,Vector
使用本地方法System.arraycopy移动数组元素,新增元素时如果当前数组空间不足,则自动扩容以保证足够的空间存储元素,Vector每个操作方法都指定了synchronized关键字,因此Vector的操作时线程安全的。
适用场景:Vector
的适用于读多写少,线程安全的业务场景。
(2)ArrayList,ArrayList和Vector非常相似,区别仅仅是ArrayList操作方法不是线程安全的,要把非线程安全的arraylist转变线程安全可以使用Collections.synchronizedList方法
适用场景:ArrayList的适用于读多写少,线程非安全的业务场景。
(3)LinkedList,List的链表实现,如下图源码结构,可以看出LinkedList主要有3个成员变量,size:链表大小,first:是链表开始节点,last:是链表尾部节点。
那LinkedList元素保存在那里呢?内部使用静态内部类Node<E>来保存数组元素,看下面代码:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
通过代码可以看到,LinkedList节点类Node<E>包含了元素E,以及节点的前一个和后一个元素的引用。下面我们看看LinkedList读取,新增,删除元素时的操作
(1)读取一个元素,当读取第一个和最后一个元素时,直接返回first,last节点的成员变量E的值即可,当随机获取一个元素时,LinkedList通过 Node<E> node(int index){}方法找到指定位置index元素节点,
具体实现代码如下:
Node<E> node(int index) {
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
可以看到LinkedList查找元素必须遍历节点元素,当index < (size >> 1)也就是size/2时,从first开始遍历,否则从last遍历,这样一定程度上可以减少遍历次数。
(2)新增元素,当新增到链表头和链表尾时,直接改变元素前后指针即可,当随机添加元素到任意位置时,代码如下:
public void add(int index, E element) {
checkPositionIndex(index); //检查index是否合法
//判断index是否在链表尾
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));//node()方法定位index元素位置,找到index位置元素,添加新的元素
}
LinkedList随机新增元素也是要遍历链表,当链表较大时性能比较差。
(3)删除元素,同样当删除链表头和链表尾时,直接改变元素前后指针即可,当随机删除元素到任意位置时,代码如下:
public E remove(int index) {
checkElementIndex(index);//检查index是否合法
return unlink(node(index));//node()方法定位index元素位置,找到index位置元素,删除元素
}
特点原理:集合元素无上限,集合使用Node<E>类保存元素E,读取,新增,删除链表头和尾效率非常快。随机读取,新增,删除链表头和尾效率较差!
适用场景:顺序读取,新增,删除场景,不适合随机读写,线程不安全。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树