2018-03-23
JavaSE-集合基础
[TOC]
1.集合的并发问题
Java快速失败与安全失败迭代器 :
java迭代器提供了遍历集合对象的功能,集合返回的迭代器有快速失败型的也有安全失败型的,快速失败迭代器在迭代时如果集合类被修改,立即抛出ConcurrentModificationException异常,而安全失败迭代器不会抛出异常,因为它是在集合类的克隆对象上操作的。
java快速失败迭代器 : 大多数集合类返回的快速失败迭代器在遍历时不允许结构性修改(结构性修改指添加,删除和更新一个元素)当遍历的同时被结构性修改,会改变modCount的值, 就会抛出ConcurrentModificationException异常,而当集合是被迭代器自带的方法(如remove())修改时,不会抛出异常。
java安全失败迭代器 : 安全失败迭代器在迭代中被修改,不会抛出任何异常,因为它是在集合的克隆对象迭代的,所以任何对原集合对象的结构性修改都会被迭代器忽略,但是这类迭代器有一些缺点,其一是它不能保证你迭代时获取的是最新数据,因为迭代器创建之后对集合的任何修改都不会在该迭代器中更新,还有一个缺点就是创建克隆对象在时间和内存上都会增加一些负担。
集合对并发问题集成了一个并发包ConcurrentModificationException
2.java中的同步容器
在java中,同步容器主要包括2类
- Vector | Stack | HashTable
- Collections类中提供的静态工厂方法创建的类
Vector实现了List接口,Vector实际上是一个数组,和ArrayList类似,但是Vector中的方法都是synchronized线程同步,即进行了同步措施.
Stack继承了Vector,也是一个同步容器,它的方法也是synchronized线程同步
HashTable实现Map接口,他和HashMap很相似,但是HashTable中使用synchronized线程同步,而HashMap是不安全的
Collections类是一个工具提供类,注意,它和Collection不同,
Collection是一个顶层的接口。
在Collections类中提供了大量的方法,比如对集合或者容器进行排序、查找等操作。最重要的是,在它里面提供了几个静态工厂方法来创建同步容器类
3.单项链表的增删
链表的增删原理需要注意,重点因为存储空间并非连续存在,不能在改变链表结构时使其断开,否则将难以再次找到到原来的标记
增加
- a的next改为a1的next
- a1的next改为a
删除
- a1的next改为a2的next
- a2的值赋给e
- 释放a2
4.ArrayList相关
4-1.ArrayList线程安全问题
ArrayList本身是线程不安全的,如果在多线程情况下使用可以考虑一下两种方案
- Collections.synchronizedList(List list)方法返回一个线程安全的ArrayList类
- concurrent并发包下的CopyOneWriteArrayList类
4-2.ArrayList实现的部分接口
ArrayList实现了List接口,继承了AbstractList (维持集合结构的本身需求)
ArrayList实现了Serialization接口,可以序列化传输
ArrayList实现了RandomAccess接口,支持快速随机访问(实际上通过下标实现快速随机访问)
ArrayList实现了Cloneable接口,可以被克隆
4-3.扩容的选择
集合中的结构都支持自动扩容
如ArrayList的扩容机制是1.5倍(1.6和1.7的区别(16/15))
ArrayList可以指定初始大小也可以默认(10个单位),使用时可以根据业务需求,通过构造设置初始容量,
- 这里考虑的因素是集合自动扩容对性能的一个损耗,如果提前知道集合内元素的大概数量,那么初始容量可以设置大一些,从而减少自动扩容的损耗
- 也可以通过ensureCapacity方法来指定扩容的长度(使用场景了解较少)
4-4.数组的底层实现
数组的引用+下标*数组数据类型的大小—>获得该元素的数据内容