集合
引言
为什么要用集合,试想一下如果让你统计一批数据, 你会如何存储?如果数据量少,你可以用变量存,但是数据多了以后你会发现,程序既不美观又不方便,这个时候想到数组,但是数组也有缺陷,创建数组时要指定其长度,并且,在使用时长度不可改变,当数据会不断增加时,我们会寻找一个拥有可变长度的容器来存储这些数据,它就是”集合“。Java为我们提供了集合,里面有各种各样的容器,每个容器长度可改变,集合更加方便和高效。
一、什么是集合
集合类是java.util中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。集合类存放的是对象,不同的集合,有不同的特点,用以适配各种不同的场合。这里主要列举两个集合的接口,Map键值对体系,Collection体系。Collection存放单一元素,Map存放键值对。
二 、Collection
2.1接口详解:特点与用途
Collection接口定义了存取对象的方法。两个非常常用的子接口:List接口:存放的元素有序且允许有重复的集合接口。Set接口:存放的元素无序不包含重复的集合接口,所有的重复内容是靠hashCode()和euqals()两个方法区分的。 Collection框架结构如下图示:
2.2接口实现类:
name | 特点 | 优点 | 缺点 |
---|---|---|---|
ArrayList | 有序 可重复 可为null | 查询快 | 增删慢 |
LinkedList | 有序 可重复 可为null | 增删快 | 查询慢 |
HashSet | 无序 值唯一 可为null | 增删改查快 | 无序 |
TreeSet | 对值排序 无序 值不可为null 值为一 | 对值排序 | 无序 |
LinkedHashSet | 有序 值唯一 可为null | 有序 增删快 | 查询慢 |
2.3集合的方法和操作:
Set方法分类:
List方法分类:
三 、Map
3.1接口详解:特点与用途
Java提供了专门的集合类用来存放 映射 这种一一对应的 关系的对象,即java.util.Map接口。Map是一个接口,有多种具体的实现类,常用的有HashMap和Hashtable类实现。Map中存入的对象是一对一对的,即每个对象和它的一个名字(键)关联在一起,Map框架结构如下图示:
3.2接口实现类:
场景。
name | 特点 | 优点 | 缺点 |
---|---|---|---|
TreeMap | 对key排序 无序 key不可为null key值唯一 | 对key排序 | 无序 |
LinkedHashMap | 有序 key唯一 key可以为null | 有序 | |
HashMap | 无序 key唯一 key可以为null | 增删改查快 | 无序 |
3.3集合的方法和操作:
Map方法分类:
四、集合常见问题
4.1 fail-fast 快速失败机制
java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。
例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast机制。
原因:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
解决办法:
在遍历过程中,所有涉及到改变modCount值得地方全部加上synchronized。使用CopyOnWriteArrayList来替换ArrayList
4.2 ArrayList和LinkedList的区别?
- LinkedList 实现了 List 和 Deque 接口,一般称为双向链表;
- ArrayList 实现了 List 接口,动态数组;
- LinkedList 在插入和删除数据时效率更高,ArrayList 在查找某个 index 的数据时效率更高;
- LinkedList 比 ArrayList 需要更多的内存
;