javaSE-集合

2018-03-23

JavaSE-集合基础

[TOC]

1.集合的并发问题

Java快速失败与安全失败迭代器 :

java迭代器提供了遍历集合对象的功能,集合返回的迭代器有快速失败型的也有安全失败型的,快速失败迭代器在迭代时如果集合类被修改,立即抛出ConcurrentModificationException异常,而安全失败迭代器不会抛出异常,因为它是在集合类的克隆对象上操作的。

java快速失败迭代器 : 大多数集合类返回的快速失败迭代器在遍历时不允许结构性修改(结构性修改指添加,删除和更新一个元素)当遍历的同时被结构性修改,会改变modCount的值, 就会抛出ConcurrentModificationException异常,而当集合是被迭代器自带的方法(如remove())修改时,不会抛出异常。

java安全失败迭代器 : 安全失败迭代器在迭代中被修改,不会抛出任何异常,因为它是在集合的克隆对象迭代的,所以任何对原集合对象的结构性修改都会被迭代器忽略,但是这类迭代器有一些缺点,其一是它不能保证你迭代时获取的是最新数据,因为迭代器创建之后对集合的任何修改都不会在该迭代器中更新,还有一个缺点就是创建克隆对象在时间和内存上都会增加一些负担

集合对并发问题集成了一个并发包ConcurrentModificationException

2.java中的同步容器

在java中,同步容器主要包括2类

  1. Vector | Stack | HashTable
  2. Collections类中提供的静态工厂方法创建的类

Vector实现了List接口,Vector实际上是一个数组,和ArrayList类似,但是Vector中的方法都是synchronized线程同步,即进行了同步措施.

Stack继承了Vector,也是一个同步容器,它的方法也是synchronized线程同步

HashTable实现Map接口,他和HashMap很相似,但是HashTable中使用synchronized线程同步,而HashMap是不安全的


Collections类是一个工具提供类,注意,它和Collection不同,

Collection是一个顶层的接口。

在Collections类中提供了大量的方法,比如对集合或者容器进行排序、查找等操作。最重要的是,在它里面提供了几个静态工厂方法来创建同步容器类


3.单项链表的增删

链表的增删原理需要注意,重点因为存储空间并非连续存在,不能在改变链表结构时使其断开,否则将难以再次找到到原来的标记

增加

  1. a的next改为a1的next
  2. a1的next改为a

删除

  1. a1的next改为a2的next
  2. a2的值赋给e
  3. 释放a2

4.ArrayList相关

4-1.ArrayList线程安全问题

ArrayList本身是线程不安全的,如果在多线程情况下使用可以考虑一下两种方案

  1. Collections.synchronizedList(List list)方法返回一个线程安全的ArrayList类
  2. 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.数组的底层实现

数组的引用+下标*数组数据类型的大小—>获得该元素的数据内容