目录
集合概述
1、集合类存放于java.util包中。
2、集合类型主要有3种:set(集)、list(列表)和map(映射)。
3、集合存放的都是对象的引用,而非对象本身。所以我们称集合中的对象就是集合中对象的引用。
简单来讲:集合就是一个放数据的容器,准确的说是放数据对象引用的容器
Java 集合框架主要结构图
1、集合主要分为Collection和Map两个接口
2、Collection又分别被List和Set继承
3、List被AbstractList实现,然后分为3个子类,ArrayList,LinkList和Vector
4、Set被AbstractSet实现,又分为2个子类,HashSet和TreeSet
5、Map被AbstractMap实现,又分为2个子类,HashMap和TreeMap
6、Map被Hashtable实现
Collection接口介绍
所有的方法
List接口
ArrayList
List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
基本特点:
- ArrayList中的元素和可以重复
- 是有序的集合
- 长度不固定
- 不是线程安全的,效率高
LinkedList
List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。
除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。
这些操作允许将链接列表用作堆栈、队列或双端队列。
不是线程安全的。
特有的一些方法:
Vector
和ArrayList功能类似,最主要的区别就在于vector是线程并发安全的。
但是缺点是效率比较低。
Set
一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。
HashSet
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
HashSet的唯一性:
在HashSet做添加的时候会逐个来判断当前集合中的对象和要添加的对象的比较
通过以下的条件判断两个对象是否相等
- e.hash == hash && ((k = e.key) == key || key.equals(k))
- hash值必须相等并且两个对象的地址值相等或者equals返回true
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
特点:
- 元素唯一性
- 无序性
- 允许null存在一个
- 不是线程安全(效率高)
之所以允许null存在一个是因为在源码中null被当作0看待
LinkedHashSet
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。
特点:
- 元素唯一性
- 有序的
- 允许null存在一个
- 不是线程安全(效率高)
TreeSet
TreeSet可以支持自定义排序,如果TreeSet所存储的对象的类没有实现Comparable接口就会报错ClassCastException。
所以我们如果想要使用TreeSet来对自定义的对象来排序必须实现Comparable接口。
特点:
- 元素唯一性
- 可自定义排序的
- 不允许null存在
- 不是线程安全
Map接口介绍
Map即使键值对的集合的接口抽象。
我们可以通过key的值来获得相应的值,将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。键只允许有一个空值,值可以有多个空值。
Map的特点:
- 数据成对出现
- 数据的键是唯一的
- 一个键只能对应一个值
- 值可以重复
- 键允许有一个为空,值可以多个是空
所有方法:
HashMap
HashMap的特点:
- HashMap是map的实现类
- 允许多个null值和一个null键
- HashMap中的元素没有顺序(跟添加的顺序无关)
- HashMap不是线程安全的
TreeMap
TreeMap可以参考TreeSet,TreeMap可以支持Map的排序
该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法
TreeMap特点:
- 可以按着key来做排序
- Key不能null,key不能重复,值可以有多个null
- 不是线程安全的
HashTable
HashTable的特点:
- HashTable是map的实现类
- 不允许任何null值和null键
- HashTable中的元素没有顺序(跟添加的顺序无关)
- HashTable是线程安全的。
LinkedHashMap
LinkedHashMap的特点:
- LinkedHashMap是map的实现类
- 允许多个null值和一个null键
- LinkedHashMap有顺序(添加的顺序)
- LinkedHashMap不是线程安全的
集合遍历时修改元素出现并发问题解决方法
public static void main(String[] args) {
// 创建List集合对象
List list = new ArrayList();
// 添加元素
list.add("中国");
list.add("美国");
list.add("日本");
// 迭代器遍历 出现异常
// Iterator it = list.iterator();
// while (it.hasNext()) {
// String s = (String) it.next();
// if ("中国".equals(s)) {
// list.add("韩国");
// }
// }
// 方案1:迭代器迭代元素,迭代器修改元素
// 而Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator
// ListIterator lit = list.listIterator();
// while (lit.hasNext()) {
// String s = (String) lit.next();
// if ("中国".equals(s)) {
// lit.add("韩国");
// }
// }
// 方案2:集合遍历元素,集合修改元素(普通for)
for (int x = 0; x < list.size(); x++) {
String s = (String) list.get(x);
if ("中国".equals(s)) {
list.add("韩国");
}
}
System.out.println("list:" + list);
}
在迭代器和增强for循环里直接修改集合是会出现并发异常