前言
Java的集合类可以说是我们编程中最常用的一种容器了,用来存放多个对象的引用,实现常用的数据结构,如队列、栈等。常用的集合类有Set、List、Map、Queue(Java5增加),但是大多数程序员还是会习惯性的忽略Queue,而只认为集合对象为前三者。
划分
按照接口的派生来说,集合可以划分为两大类。
- Collection接口派生:List、Set
- Map接口派生:Map
但是按照我的理解,还可以有一种划分形式,那就是按照实现原理来划分,List是一类,Map和Set是一类。
- 无序不重复:Map、Set
- 有序可重复:List
为什么这么说呢,首先,List集合类似一个数组,它可以记住集合容器内元素添加的顺序,且长度是可变的。而Map和Set类似一个桶,我们把元素一股脑的全部丢到桶中,无法记录其添加顺序,这就解释了为什么Set元素和Map的Key是不能重复的,元素本身就无序了,再重复的话,我们想从中准确查找某一个元素该怎么办呢?
其实看过Set源码的同学就会发现,Set的实现可以说就是一个所有value值为null的Map结构。Java先实现了Map,再包装一个所有value值为null的Map来实现Set。
不仅如此,Set和Map的子类实现也惊人地相似。
- Set的子类实现:HashSet、LinkedHashSet、SortedSet(Interface)、TreeSet、EnumSet。
- Map的子类实现:HashMap、LinkedHashMap、SortedMap(Interface)、TreeMap、EnumMap。
所以在想要系统的掌握集合的相关知识时,通过实现上的相似之处,可以通过推导的方式记忆有关集合的知识。
Collection接口方法
Collection是List、Set的父接口,在父接口中定义了Collection所有子类实现的通用基本操作。诸如add、addAll、clear、contains、containAll…等等。在这里就不一一赘述,大家都应该用过且api中都查得到。
实际应用中,我们根本无需对这些方法死记硬背,只需记住集合类就像容器,容器的功能无非逃不开添加对象、删除对象、清空容器、容器中有没有某个东西、判断容器是否为空等,集合类的方法就是这些功能的实现。
Iterator迭代器
Iterator是Java集合中的重要成员,主要用于遍历Collection集合中的元素,因此也被叫做迭代器。它不像其他集合那样,作为容器用于存放对象,且本事并不具备存放对象的能力。
Iterator的方法有:
- boolean hasNext():如果被迭代的元素还没遍历完,返回true
- Object next():返回集合中的下一个元素的值
- void remove():删除迭代器中上一个next方法返回的元素的值
- void forEachRemaining(Consumer action):Java8新增遍历方法
注意上面文字中加粗的地方,以前见过很多人有这样的误区,Iterator中迭代的就是集合本身,其实这是不对的。
当Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传递给了迭代变量,而是把集合元素的值传递给了迭代变量,所以修改迭代变量的值,对于被迭代的集合本身是没有任何影响的。
还有一点要注意的是,Iterator迭代器采用的是快速失败(fail-fast)机制,一旦系统发现集合的值在迭代过程中,该集合内的元素被其他线程所修改,程序会立刻抛出ConcurrentModificationException,这样做可以避免线程间共享资源的不同步问题,也算是线程安全的一种体现。
后续会分别详细记录关于Set、List和Map的知识点归纳,方便日后时常翻阅。