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详解相关推荐

  1. java技术详解_Java反射技术详解及实例解析

    前言 相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替 ...

  2. java中匿名内部类详解_java 中匿名内部类的实例详解

    搜索热词 java 中匿名内部类的实例详解 原来的面貌: class TT extends Test{ void show() { System.out.println(s+"~~~哈哈&q ...

  3. java web编码详解_java web 开发 编码问题详解

    java web 开发 编码问题详解 浏览器 IE/FireFox ------------->Servlet容器-------------------------->显示页面 编码   ...

  4. java 枚举使用简书_java枚举类型使用和详解

    1.定义 An enum type is a special data type that enables for a variable to be a set of predefined const ...

  5. java vm 远程监控配置文件_Java VisualVM监控远程JVM(详解)

    我们经常需要对我们的开发的软件做各种测试, 软件对系统资源的使用情况更是不可少, 目前有多个监控工具, 相比JProfiler对系统资源尤其是内存的消耗是非常庞大,JDK1.6开始自带的VisualV ...

  6. java list详解_Java 中 list 用法案例详解

    LIST是个容器接口可以理解为动态数组,传统数组必须定义好数组的个数才可以使用,而容器对象无须定义好数组下标总数,用add()方法即可添加新的成员对象,他可以添加的仅仅只能为对象,不能添加基本数据类型 ...

  7. java 工厂模式详解_java 工厂模式的实例详解

    java 工厂模式的实例详解 工厂方法中的"工厂"和我们平常理解的一样:用于生产产品. 而客户是要和产品打交道,所以工厂方法模式的意义在于把客户和产品分开,达到解耦和更灵活的目的. ...

  8. file java详解_Java中File的实例详解

    Java中File的实例详解 File 代表文件或者目录的类 构造函数 File(File parent,String child)---代表了指定父目录下的指定的子文件或者子目录 File(Stri ...

  9. java的sort的用法_Java排序方法sort用法详解

    Java排序方法sort用法详解 发布于 2020-2-28| 复制链接 摘记: 本文实例为大家分享了java对数组.集合的排序方法,供大家参考,具体内容如下对数组的排序: ```java //对数组 ...

最新文章

  1. 扩增子图表解读5火山图:差异OTU数量及变化规律
  2. Kotlin特色之object、let、with、run、apply、also函数的使用
  3. linux mv命令改名,linux中mv命令使用详解(移动文件或者将文件改名)
  4. 树莓派上搭建svn服务器
  5. java io操作_Java IO 操作
  6. Angular使用Console.log()打印出来的数据没问题,点击详情后数据变了
  7. 美团点评移动网络优化实践
  8. 手把手教你用Python实现“坦克大战”,附详细代码!
  9. 基于openvswitch+Docker构建SDN网络测试环境 (使用ovs-docker进行构建)
  10. 判断页面环境是否在小程序的webview中
  11. 关于域名注册、投资问题的相关解释
  12. 关于Microsoft Office 2007 Beta 简体中文版的一些消息
  13. java做校园一卡通技术_基于jsp的校园一卡通管理系统-JavaEE实现校园一卡通管理系统 - java项目源码...
  14. Fddb数据集人脸label可视化(matlab)
  15. 利用python脚本将微信聊天信息提取到txt文件
  16. MySQL参数max_connect_errors分析释疑
  17. JavaScript模式:字面量和构造函数
  18. html在搜索栏中加入放大镜,CSS3 搜索条动画(放大镜图标展开为长方形输入框)...
  19. 人脸识别最低像素_人脸识别新利器:让你在50米内无处遁逃
  20. 【阅读笔记】使用决策树预测泰坦尼克号幸存者实例 - scikit-learn机器学习

热门文章

  1. Windows Terminal Preview 1.3 发布
  2. php如何修改二维数组的值,php如何改变二维数组的值
  3. java 强制类型转换_lt;08gt;数据类型转换
  4. c++ 随机字符串_第3章 别碰白块(《C和C++游戏趣味编程》配套教学视频)
  5. elemenetui 布局_2020 零基础到快速开发 Vue全家桶开发电商管理系统(Element-UI)主页布局开发-Go语言中文社区...
  6. Expected one result (or null) to be returned by selectOne(), but found: 7
  7. php is_subclass_of,PHP_PHP is_subclass_of函数的一个BUG和解决方法,is_subclass_of的作用: 复制代码 - phpStudy...
  8. for mew歌词 shell_求shell for mew的中文歌词
  9. oracle数据库实践,RubyonRails连接Oracle数据库实践
  10. (万里开源)greatdb mysql 8.0以上版本创建用户并授权远程连接