浅谈Collection的入门级知识点一:Collection(List)

菜鸟级的自我成长 一、

Collection(集合)
List部分
Collection:高度抽象出来的集合,是一个接口。public interface Collectionextends Iterable{},添加、删除、清空、遍历、是否为空、获取大小、是否保护某元素等等
List:有序队列,每个元素都有其索引,可以有重复的元素
Set:元素不可重复的集合
Map:映射接口,key-value
Collection依赖于Iterator,ListIterator是专门遍历List而存在
Enumeration只能在Hashtable、Vector、Stack中使用
Arrays和Collections是操作数组、集合的两个工具

接口的所有子类必须实现两种构造函数:不带参数的和参数为Collection的构造函数,带参的i构造函数,可以直接转换Collection的类型

List:public interface List extends Collection{}
有序的队列,每个元素都有一个索引,第一个元素的索引值0,往后的元素索引值一次加1.允许有重复的元素,添加、删除、获取、修改指定位置的元素、获取List中的子队列

Set:无重复的元素 功能和Collection完全一样

AbstractColection:public absrtact class AbstractCollectionimplements Collection{}:实现了Collection中出了iterator()和size()之外所有的函数

AbstractList: 实现了List中除了size()、get(int location)之外的函数

AbstractSet:实现了Set中出了iterator()和size()之外所有的函数

Iterator:是否存在下一个元素、获取下一个元素、删除当前元素。fail-fast机制遍历

ListIterator:专门遍历List,提供向前、向后遍历,比Iterator增加了添加、手否存在上一个元素、获取上一个元素等

ArrayList:数组队列功能、随机访问功能、能被克隆、支持序列化,能通过序列化去传输,线程不安全,单线程
两个重要对象:elementData和size,elementData是一个动态数组,构造函数ArrayList(int initialCapacity)来执行它的初始容量为initialCapacity;不含参数的构造函数Array List()创建则默认容量为10.elementData数组的大小会根据ArrayList容量的增长而动态的增长。size则是动态数组的实际大小
当ArrayList的容量不足以容纳全部元素时,ArrayList会重新设置容量:新的容量=”(原始容量x3)/2+1“
其克隆函数,既是将全部元素克隆到一个数组中
当写入到输出流时,先写入”容量“,再依次写入”每一个元素“;当读出输入流时,先读取”容量“,再依次读取”每一个元素“。 ”

调用ArrayList中的toAttay()异常,类型转化时须调用 T[] toArray(T[] contents)
Iterator的fail-fast机制
java集合中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件
解决办法:使用“Java.util.concurrent包下的类”去替代“Java.util包下的类”。(Java.util.concurrent包下的CopyOnWriteArraylist并没有继承AbstractList,仅实现了List接口。)
fail-fast原理:产生fail-fast事件,是通过抛出ConcurrentModificationException异常来触发的,ConcurrentModificationException是在操作Iterstor时抛出的异常,expectedModCount在创建Iterator的对象Itr时,被赋值为modCount,通过Itr,我们知道:expectedModCount不可能被修改为不等于modCount,在Array List源码中,可以发现,只要涉及到修改集合中的元素个数时,都会改变modCount的值。那么fail-fast的产生究竟是怎么回事呢?
(01)新建了一个ArrayList,名称为arrayList;
(02)向arrayList中添加内容
(03)新建一个“线程a”,并在“线程a”中通过Iterator反复读取array List的值
(04)新建一个“线程b”,并在“线程b”中删除arrayList中 的一个“节点A”
(05)这时,就会产生有趣的事件了。
在某一时刻,“线程a”创建了arrayList的Iterator。此时“节点A”仍然存在于arrayList中,创建arrayList时,expectedModCount = modCount(假设它们此时的值为N)。
在“线程a”在遍历arrayList过程中的某一时刻,“线程b”执行了,并且“线程b”删除了arrayList中的“节点A”。“线程b”执行remove()进行删除操作时,在remove()中执行了“modCount++”,此时modCount变成了N+1!
“线程a”接着遍历,当它执行到next()函数时,调用checkForComodification()比较“expectedModCount”和“modCount”的大小;而“expectedModCount=N”,“modCount=N+1”,这样,便抛出ConcurrentModificationException异常,产生fail-fast事件。

LinkedList:可以被当作堆栈、队列、双端队列进行操作、能克隆、支持序列化、非同步,其本质是双向链表
两个重要对象:header 和size
header是双向链表的表的表头,是双向链表节点所对应的类Entry的实例,Entry中包含成员变量:previous(该节点的上一个节点),next(该节点的下一个节点),element(该节点所包含的值)
size是双向链表中节点的个数
其顺序访问会非常高效,而随机访问效率比较低
(01)LinkedList实际上是通过双向链表去实现的。内部类Entry是双向链表节点所对应的数据结构,它包括的属性:当前节点所包含的值,上一个节点,下一个节点
(02)不存在容量不足的问题
(03)克隆函数是将全部元素克隆到一个新的LinkegdList对象中
(04)当写入到输出流时,先写入“容量”,再依次写入“每一个节点保护的值”当写入输入流时,先读取“容量”,再依次读取“每一个元素”
(05) 第一个元素(头部) 最后一个元素(尾部)
抛出异常 特殊值 抛出异常 特殊值
插入 addFirst(e) offerFirst(e) addLast(e) offerLast(e)
移除 removeFirst() pollFirst() removeLast() pollLast()
检查 getFirst() peekFirst() getLast() peekLast()
(06)可以作为FIFO(先进先出)的队列
队列方法 等效方法
add(e) addLast(e)
offer(e) offerLast(e)
remove() removeFirst()
poll() pollFirst()
element() getFirst()
peek() peekFirst()
(07)可以作为LIFO(后进先出)的栈
栈方法 等效方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst()

Vector:矢量队列,支持相关的添加、删除、修改、遍历,提供随机访问,能被克隆,线程安全
包含了三个成员变量:elementData(“Object[]类型的数组”保存了添加到Vector中的元素,是一个动态数组)、elemenrCount(动态数组的实际大小)、capacityIncrement(动态数组的增长系数)
(01)通过数组保存数据,默认大小为10
(02)扩容根据容量增加系数,不到一时。增加一倍
(03)克隆函数时,将全部函数克隆到一个数组中去
建议随机访问

stack:栈,特性:先进后出,继承与Vector,通过数组实现
(01)push时(将元素推入栈中)通过将元素追加的数组的末尾
(02)peek时(取出栈顶元素、不执行删除)返回数组末尾的元素
(03)pop时(取出栈顶元素,并将该元素删除)取出数组末尾元素,然后将该元素从数组中删除
(04)拥有Vector的属性和功能

总结:
(01) List 是一个接口,它继承于Collection的接口。它代表着有序的队列。
(02) AbstractList 是一个抽象类,它继承于AbstractCollection。AbstractList实现List接口中除size()、get(int location)之外的函数。
(03) AbstractSequentialList 是一个抽象类,它继承于AbstractList。AbstractSequentialList 实现了“链表中,根据index索引值操作链表的全部函数”。
(04) ArrayList, LinkedList, Vector, Stack是List的4个实现类。
  ArrayList 是一个数组队列,相当于动态数组。它由数组实现,随机访问效率高,随机插入、随机删除效率低。
  LinkedList 是一个双向链表。它也可以被当作堆栈、队列或双端队列进行操作。LinkedList随机访问效率低,但随机插入、随机删除效率高。
  Vector 是矢量队列,和ArrayList一样,它也是一个动态数组,由数组实现。但是ArrayList是非线程安全的,而Vector是线程安全的。
  Stack 是栈,它继承于Vector。它的特性是:先进后出(FILO, First In Last Out)。
涉及到“栈”、“队列”、“链表”时考虑使用List
(01)对于需要快速插入,删除元素,应该使用LinkedList
(02)对于需要快速随机访问元素,使用ArrayList
(03)对于“单线程环境”或者“多线程环境,但List仅仅只会被单个线程操作”应选择使用非同步的类(ArrayList)对于“多线程环境,且List可能同时被多个线程操作”选用同步的类(Vector)
(04)对于需要快速插入,删除元素,使用LinkedList
(05)对于需要快速随机访问元素,使用ArrayList
(06)对于“单线程环境”或“多线程环境,但List仅仅只会被单个线程操作”,此时应该使用非同步的类

LinkedList与ArrayList的性能差异分析
插入效率比较
在LinkedList中,插入时,先在双向链表中找到要插入节点的位置index;找到之后,在插入下一个新节点,双向链表查找index位置节点时,有一个加速动作:会根据链表自身长度的1/2比较哪头近,从那头开始查找
LinkedList中,arraycopy()是一个jni函数,再添加之后,会移动index之后的所有元素。
随机访问效率比较
在Linked List中,在get()获取Linked List第index个元素时,通过双向链表找到要index位置的元素,找到之后返回;
在ArrayList中,通过get()直接获取ArrayList第index个元素,直接返回值

Vector与Array List比较
相同点
(01)都是list
(02)都实现了RandomAcess和Cloneable接口:支持快速随机访问、克隆自己
(03)都是通过动态数组实现
(04)默认数组容量都是10
(05)都支持Iterator与listIterator遍历
不同点
(01)ArrayList线程不安全;Vector线程安全支持同步的
(02)ArrayList支持序列化,Vector不支持,因为ArrayList实现了Java.io.Serializable接口
(03)ArrayList3个构造函数,Vector4个构造函数自己多支持了制定容量增加系数
(04)ArrayList容量不足时,“新的容量=(原始容量x3)/2+1”;Vector容量增长与“增长系数”有关,若指定了“增长系数”,且“增长系数>0”那么,每次容量不足时,“新的容量”=“原始容量”+“增长系数”若增长系数无效则为原始容量x2
(05)Vector支持Enumeration遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值