java.util包.

与Set不同, List允许重复的元素。即 e1.equals(e2)。

部分方法定义

  • int size();

返回列表中元素的个数,如果超过Integer.MAX_VALUE,就返回Integer.MAX_VALUE

  • boolean isEmpty();
  • boolean contains(Object o);

对于目标元素o, 如果列表中至少存在一个元素e:o==null? e==null ; o.eqauls(e)。

如果目标元素不可比较,将会抛出异常:ClassCastException.

如果目标元素为null,并且该列表不允许null元素,则抛出异常:NullPointerException.

  • Iterator<E> iterator();
  • Object[] toArray();

以恰当的顺序返回列表中的所有元素。

返回的数组是安全的,因为它的引用不是由该列表维护的。也就是说,该方法必须申请一个新的数组,即使list本身就是基于数组的。因此,调用者可以自由地修改返回的数组。

该方法作为一个桥梁,建立起基于数组和基于集合的API。

  • <T> T[] toArray(T[] a);

返回数组的运行时类型是指定的数组类型。

如果列表恰好是该类型的,就会直接返回。否则,必须申请一个新数组,新数组的大小恰好就是列表的size。

如果列表是指定类型的,并且数组中还有剩余空间,则未使用的数组位置全部置null。——这一点很有用,因为可以判断列表的长度。前提是调用者知道该list不会包含任何null元素。

  • boolean add(E e);

支持该操作的List,可能会限制允许加入该list的元素。比如,有些list可能会拒绝添加null作为元素,而其他list有可能限制元素的类型。

UnsupportedOperationException, 如果该List不支持add方法。

ClassCastException, 指定元素的类class,不允许它被添加到该list中。

NullPointerException,如果指定元素是null,并且该List不允许null元素。

IllegalArgumentException,如果该元素的某些属性,不允许它被添加到该list中。

  • boolean remove(Object o);

删除第一次出现的那个元素,即下标最小的: o==null ? get(i )==null : o.eqauls(get(i );

如果列表中不包含这样的元素,就不变。

ClassCastException,如果指定元素的类型无法与list匹配。

NullPointerException, 如果指定元素是null,并且list不允许null元素。

UnsupportedOperationException,list不支持remove方法。

  • boolean containsAll(Collection<?> c);

如果列表中包含了指定collection中的所有元素,返回true。

ClassCastException,如果指定collection中的一个或多个元素的类型与该list不匹配

NullPointerException,指定collection中包含一个或多个null,而list不允许null元素。

  • boolean addAll(Collection<? extends E> c);

UnsupportedOperationException

ClassCastException

NullPointerException

IllegalArgumentException

  • boolean addAll(int index, Collection<? extends E> c);

在指定的下标处插入指定collection中的所有元素。

IndexOutOfBoundsException,如果下标超出范围。

  • boolean removeAll(Collection<?> c);

删除list中所有在c中出现的元素。

  • boolean retainAll(Collection<?> c);

保留指定集合中出现的所有元素。

NullPointerException, 如果list中包含一个null,而指定的collection是不允许null的时候。

ClassCastException

  • void clear();
  • boolean equals(Object o);

两个list相等的条件是:他们包含相同的元素,以相同的顺序。

  • int hashCode();

  • E get(int index);
  • E set(int index, E element); //替换已有下标处的元素
  • void add(int index, E element);
  • E remove(int index);
  • int indexOf(Object o);

如果存在,就返回第一次出现的下标。如果不存在,返回-1.

  • int lastIndexOf(Object o);
  • ListIterator<E> listIterator();
  • ListIterator<E> listIterator(int index); //从指定的下标开始遍历
  • List<E> subList(int fromIndex, int toIndex);

返回一个视图。包含左下标,不包含右下标。

返回的List是基于原list的,所以在返回的list中进行的非结构性修改会在原list中体现,反之亦然。

任何针对局部范围list的操作,都可以通过传递一个subList视图来代表整个list。例如,下列语句删除了list中的部分元素:

list.subList(from, to).clear();

ArrayList

List接口的一种可调整大小的基于数组的实现。实现了所有可选的list操作,也允许所有元素,包括null。

另外,该类还提供了操纵底层实现数组的大小的方法。

该类和Vector类基本是一样的,除了ArrayList是非同步的。

以常数时间运行的方法:size, isEmpty, get, set, iterator, listIterator。摊销的常数时间,即O(n ):add。粗略来说,其他方法的运行时间都是线性的。常数因子比起LinkedList要小。

每个ArrayList的实例都有一个容量capacity。这是底层数组的大小。通常,容量至少要和List的大小一样大。因为增加一个元素有常数的摊销时间,所以没有明确规定增长策略的细节。

在增加大量元素之前扩容的一个办法是使用ensureCapacity操作,这可以减少容量调整的次数。

注意ArrayList是非同步的。如果多线程同时访问同一个ArrayList实例,并且至少有一个线程修改了列表结构,就必须要有外部的同步机制。通常通过同步某些封装了该list的对象来实现,如果没有这样的对象,该list就应该使用Collections.synchronizedList()来包装。最好在创建时就这样做,可以避免对该list的意外的非同步访问。(结构性修改是指,增加或删除一个或多个元素,或者调整了底层数组的大小,只修改了元素的值不是结构性修改)。

ArrayList中的iterator()方法和listIterator()返回的迭代器都是快速失败的。如果在创建了该迭代器之后的任意时间对list进行了结构性修改,除了通过iterator本身提供的方法之外,该Iterator都会抛出一个ConcurrentModificationException异常。面对同时发生的修改,iterator会快速干脆地失败,而不是无法确定未来的冒险的、非确定性的行为。

注意,iterator提供的快速失败机制并不能保证线程安全。快速失败机制应该只用于检测bug。

AbstractList源码

抽象类实现了部分方法。

ArrayList源码细节

ArrayList继承自AbstractList抽象类。

成员变量

构造方法

get()方法

set()方法

add()方法

扩容

contains()方法

remove()方法

clear()方法

clone()方法

转换为数组

迭代器 iterator 和 listIterator

【关于Itr中的remove()方法】

注意到lastRet表示上一次读取的位置,当这个位置为-1时,remove方法抛出IllegalStateException。而这个位置 为-1的情况,一个是初始化时,还未调用过next(),另一个是在调用了remove()方法后。所以,在这两种情况下是不能调用remove()方法的,即remove()方法不能连续调用,必须和next()结合,先next()后remove()。

另外,在删除元素时,会同步更新iterator中的expectedModCount,这样保持和List中的modCount的一致,从而使得checkForComodification()检测通过,本质上并不是线程同步的,当多个Iterator同时访问同一个List时,仍然是不安全的。

【ListItr】

在Itr的基础上,增加了向前遍历的方法,相当于一个双向遍历器。还增加了set()和add()方法,使得遍历器不仅可以删除元素,还可以修改和增加元素。

特别注意的,add()方法和remove()方法都会修改lastRet值为-1,因此需要读取lastRet的方法,譬如set(),remove()都不能在这两个方法后面调用,需要先调用一次next()方法。

List的add()和remove()方法都是结构性的修改,所以迭代器中的add()和remove()方法需要同步更新modCount的值,否则会在下一次增删改查操作时,检测到不相同,而抛出ConcurrentModificationException。

子列表视图

List(JDK1.7)(1)的更多相关文章

  1. Java集合:ArrayList (JDK1.8 源码解读)

    ArrayList ArrayList几乎是每个java开发者最常用也是最熟悉的集合,看到ArrayList这个名字就知道,它必然是以数组方式实现的集合 关注点 说一下ArrayList的几个特点,也 ...

  2. Web service project中导入的库JAXB(JDK1.7新产品,组成部分)

    JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向 ...

  3. Java集合:LinkedList (JDK1.8 源码解读)

    LinkedList介绍 还是和ArrayList同样的套路,顾名思义,linked,那必然是基于链表实现的,链表是一种线性的储存结构,将储存的数据存放在一个存储单元里面,并且这个存储单元里面还维护了 ...

  4. 导入一个新项目需要注意的几大问题(jdk1.6+eclipse4.4+tomcat6)

    今天导项目犯了一个很低级的错误,浪费了半个小时,所以在此罗列出在导一个新的项目到eclipse中时需要注意的几个问题,希望对大家有所帮助. 将项目从svn或者github等项目版本控制软件上拷贝下来, ...

  5. HashMap源码(JDK1.8)-手动注释

    HashMap简介 HashMap是一种K-V映射的一种数据结构,通过K(key)值能实现在O(1)的时间复杂度下找到对应的V(value).JDK1.8之前,HashMap的底层数据结构是数组+链表 ...

  6. java基础知识回顾之java Thread类学习(八)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解

    看API文档介绍几个方法:  JDK1.5中提供了多线程的升级解决方案: 特点: 1.将同步synchronized显示的替换成Lock                    2.接口Conditio ...

  7. javase基础回顾(一)ArrayList深入解析 解读ArrayList源代码(JDK1.8.0_92)

    我们在学习这一块内容时需要注意的一个问题是 集合中存放的依然是对象的引用而不是对象本身. List接口扩展了Collection并声明存储一系列元素的类集的特性.使用一个基于零的下标,元素可以通过它们 ...

  8. ConcurrentHashMap源码解析(JDK1.8)

    package java.util.concurrent; import java.io.ObjectStreamField; import java.io.Serializable; import ...

  9. 使用ArrayList时代码内部发生了什么(jdk1.7)?

    前言 ArrayList(这里的ArrayList是基于jdk1.7)是在项目中经常使用的集合类,例如我们从数据库中查询出一组数据.这篇文章不去剖析它的继承和实现,只是让我们知道实例化及增删改查时它的 ...

  10. Java基础系列--HashMap(JDK1.8)

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...

随机推荐

  1. APP案例分析-热血江湖

    本次分析的是一款游戏名叫热血江湖,这是我上小学的时候就在玩的游戏,可以说是一直玩到现在所以对它有一定的感情,所以决定分析这款游戏.下面附一张现在的游戏登陆界面. 第一部分 调研, 评测 1.下载软件并 ...

  2. 通过Get-Group导出组的成员

    导出组邮箱的前十个成员,需要注意的是: Get-Group没有Get-GroupMember命令,但是在结果中有一个Members的属性,这个属性包含了所有子成员的对象,用循环将它们列出来即可.有点对 ...

  3. 多校联赛7 1001 hdu 4666(最远哈曼顿距离+优先队列)

    吐个糟,尼玛今天被虐成狗了,一题都没搞出来,这题搞了N久居然还是搞不出来,一直TLE,最后还是参考别人代码才领悟的,思路就这么简单, 就是不会转弯,看着模板却不会改,艹,真怀疑自己是不是个笨蛋题意:求 ...

  4. Python高级特性:Python迭代、生成器、列表生成式

    迭代 给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历称为迭代(Iteration). 在java和C语言中,迭代是通过循环list的下标来完成的,Pyth ...

  5. mysql实现消息队列

    mysql之消息队列   消息队列:在消息的传输过程中保存消息的容器. 消息队列管理器在将消息从它的源中继到它的目标时充当中间人.队列的主要目的是提供路由并保证消息的传递:如果发送消息时接收者不可用, ...

  6. 数据库优化之SQL语句优化-记录

    1. 操作符优化 (a) IN 操作符 从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别: ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查 ...

  7. 【版本管理】git本地操作

    1.初始化一个Git仓库,使用git init命令. 2.添加文件到Git仓库,分两步: • 第一步,使用命令git add 文件名,注意,可反复多次使用,添加多个文件: • 第二步,使用命令git ...

  8. TreeMap源码剖析

    原文  http://blog.csdn.net/chdjj/article/details/38782221 主题 源码分析红黑树 注:以下源码基于jdk1.7.0_11 之前介绍了一系列Map集合 ...

  9. Paint Chain HDU - 3980(sg)

    因为题中是个环, 所以我们可以首先拿出一组m 如果n<m 先手必输 否则的话跑sg函数 n = n-m #include <iostream> #include <cstdio ...

  10. 【刷题】BZOJ 3262 陌上花开

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...