java list 之详解_Java高级技术之List详解
List
List是一种有序的Collection,使用此接口能够精确地控制每个元素插入的位置。用户能够使用索引来访问List中的元素,每个元素的索引是固定的,我们可以认为List是一种动态的数组。
实现List接口的常用类有LinkedList,ArrayList,Vector和Stack.
ArrayList
ArrayList的底层实现原理是开辟出一块数组区域,能够加入任何类型的元素,包括null.ArrayList的size(),isEmpty(),get(),set()方法运行时间为常数。但是使用add()方法添加n个元素需要O(n)的时间,其他的方法运行时间为线性。
也就是说,使用ArrayList是要求随机读取的场景,因为Array在随机读取的时候效率很高,但是在频繁插入和删除的场景中,效率就会相对差一些。
ArrayList的部分核心JDK源码是这样的:
//增加
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,size - index);
elementData[index] = element;
size++;
}
public boolean addAll(Collection c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
//删除
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
//查询
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
//修改
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
其中,elementData是一个Object类型的数组,用于存储元素。当添加元素的时候,需要先判断elementData数组的长度,然后为其扩容,扩容的核心函数是grow(),其源代码是:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
LinkedList
LinkedList与ArrayList类似,都类似于动态数组。与ArrayList的区别在于,LinkedList的底层数据结构是链表,这使得其在增加和删除某个元素的时候速度很快,是一个常数的复杂度,但是,在随机读取某个元素的时候,效率就会比较差,因为游标需要移动。所以,在大量增加和删除元素的时候,我们可以使用LinkedList,需要随机读取元素的时候,选用ArrayList.
此外LinkedList提供额外的get(),remove(),insert()方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
它的JDK实现源代码是:
transient int size = 0;
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node first;
/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node last;
//链表的数据结构
private static class Node {
E item;
Node next;
Node prev;
Node(Node prev, E element, Node next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
//添加元素
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
/**
* Links e as first element.
*/
private void linkFirst(E e) {
final Node f = first;
final Node newNode = new Node(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
/**
* Links e as last element.
*/
void linkLast(E e) {
final Node l = last;
final Node newNode = new Node(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
//删除
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
//查询
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
//修改
public E set(int index, E element) {
checkElementIndex(index);
Node x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
Vector & Stack
Vector与ArrayList很类似,区别是Vector的方法是同步的,这些方法被加上synchronized关键字修饰,这将在后面的高并发中具体阐述。
由Vector创建的Iterator,虽然和ArrayList创建的Iterator实现的同一接口,但是,由于Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(如添加或删除了一些元素),这时调用Iterator的方法时将抛出 ConcurrentModificationException异常,需要手动去捕获该异常。
Stack类继承自Vector,实现的是一个堆栈的数据结构。Stack提供5个额外的方法使得Vector可以被当作堆栈使用。这五个额外的方法分别是:push()和pop()方法入栈和出栈,peek()方法用于得到栈顶的元素,empty()方法测试堆栈是否为空,search()方法检测某元素在堆栈中的位置。Stack刚创建后是元素是空的。
Stack继承自Vector,自然也是由synchronized修饰过的同步容器。而除了这两个类,其他实现List接口的容器类并没有实现同步,在多线程场景下需要注意线程安全问题。有关同步容器,将在后面的高并发中具体涉及到。
java list 之详解_Java高级技术之List详解相关推荐
- java技术详解_Java反射技术详解及实例解析
前言 相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替 ...
- java中匿名内部类详解_java 中匿名内部类的实例详解
搜索热词 java 中匿名内部类的实例详解 原来的面貌: class TT extends Test{ void show() { System.out.println(s+"~~~哈哈&q ...
- java web编码详解_java web 开发 编码问题详解
java web 开发 编码问题详解 浏览器 IE/FireFox ------------->Servlet容器-------------------------->显示页面 编码 ...
- java 枚举使用简书_java枚举类型使用和详解
1.定义 An enum type is a special data type that enables for a variable to be a set of predefined const ...
- java vm 远程监控配置文件_Java VisualVM监控远程JVM(详解)
我们经常需要对我们的开发的软件做各种测试, 软件对系统资源的使用情况更是不可少, 目前有多个监控工具, 相比JProfiler对系统资源尤其是内存的消耗是非常庞大,JDK1.6开始自带的VisualV ...
- java list详解_Java 中 list 用法案例详解
LIST是个容器接口可以理解为动态数组,传统数组必须定义好数组的个数才可以使用,而容器对象无须定义好数组下标总数,用add()方法即可添加新的成员对象,他可以添加的仅仅只能为对象,不能添加基本数据类型 ...
- java 工厂模式详解_java 工厂模式的实例详解
java 工厂模式的实例详解 工厂方法中的"工厂"和我们平常理解的一样:用于生产产品. 而客户是要和产品打交道,所以工厂方法模式的意义在于把客户和产品分开,达到解耦和更灵活的目的. ...
- file java详解_Java中File的实例详解
Java中File的实例详解 File 代表文件或者目录的类 构造函数 File(File parent,String child)---代表了指定父目录下的指定的子文件或者子目录 File(Stri ...
- java的sort的用法_Java排序方法sort用法详解
Java排序方法sort用法详解 发布于 2020-2-28| 复制链接 摘记: 本文实例为大家分享了java对数组.集合的排序方法,供大家参考,具体内容如下对数组的排序: ```java //对数组 ...
最新文章
- 扩增子图表解读5火山图:差异OTU数量及变化规律
- Kotlin特色之object、let、with、run、apply、also函数的使用
- linux mv命令改名,linux中mv命令使用详解(移动文件或者将文件改名)
- 树莓派上搭建svn服务器
- java io操作_Java IO 操作
- Angular使用Console.log()打印出来的数据没问题,点击详情后数据变了
- 美团点评移动网络优化实践
- 手把手教你用Python实现“坦克大战”,附详细代码!
- 基于openvswitch+Docker构建SDN网络测试环境 (使用ovs-docker进行构建)
- 判断页面环境是否在小程序的webview中
- 关于域名注册、投资问题的相关解释
- 关于Microsoft Office 2007 Beta 简体中文版的一些消息
- java做校园一卡通技术_基于jsp的校园一卡通管理系统-JavaEE实现校园一卡通管理系统 - java项目源码...
- Fddb数据集人脸label可视化(matlab)
- 利用python脚本将微信聊天信息提取到txt文件
- MySQL参数max_connect_errors分析释疑
- JavaScript模式:字面量和构造函数
- html在搜索栏中加入放大镜,CSS3 搜索条动画(放大镜图标展开为长方形输入框)...
- 人脸识别最低像素_人脸识别新利器:让你在50米内无处遁逃
- 【阅读笔记】使用决策树预测泰坦尼克号幸存者实例 - scikit-learn机器学习
热门文章
- Windows Terminal Preview 1.3 发布
- php如何修改二维数组的值,php如何改变二维数组的值
- java 强制类型转换_lt;08gt;数据类型转换
- c++ 随机字符串_第3章 别碰白块(《C和C++游戏趣味编程》配套教学视频)
- elemenetui 布局_2020 零基础到快速开发 Vue全家桶开发电商管理系统(Element-UI)主页布局开发-Go语言中文社区...
- Expected one result (or null) to be returned by selectOne(), but found: 7
- php is_subclass_of,PHP_PHP is_subclass_of函数的一个BUG和解决方法,is_subclass_of的作用:
复制代码 - phpStudy...
- for mew歌词 shell_求shell for mew的中文歌词
- oracle数据库实践,RubyonRails连接Oracle数据库实践
- (万里开源)greatdb mysql 8.0以上版本创建用户并授权远程连接