1、概述
Java 的集合类库很是丰富,囊括了大部分的常见数据结构形式,让我们可以有目的性的选择适合当前业务场景和功能场景的集合类。合适的集合框架可以最大程度的提升执行速度和效率。
Java 集合类库中所有的集合类都始于 Collection 接口和 Map 接口,前者表示单值集合,后者表示映射集合(双值集合)。
Java 集合框架中的 Abstract 开头的抽象类,其实是 JDK 开发者定义出来用于实现具体集合类的,是面向 JDK 开发人员的,而不是面向 JDK 的使用人员。在这些抽象类中一般会将同一类型的集合的一些公共的方法进行实现,避免在具体的集合类中重复的实现,比如 contains 方法。
2、接口体系
这个结构系统中,我只是简单的列出了终止于具体集合类型接口的接口继承结构,从中可以明显的看出各个接口的位置,下面让我们来重点介绍一些这些接口,它们的位置及意义。
2.1 Iterable 接口
这是一个简单的接口,实现了该接口的类都可以使用 foreach 循环迭代,其实 foreach 底层原理还是 Iterator 迭代器循环。从上面的接口可以看出,只有单值集合可以使用这种迭代方式。
它内部只拥有一个方法:
- 1 Iterator iterator();
这个方法用于返回一个基于类型为 T 的元素集合的迭代器 Iterator。
2,2 Iterator 接口
这个接口就是迭代器接口,迭代器接口定义了迭代器常用的方法:
- boolean hasNext();
- E next();
- void remove();
这三个方法的意义各不相同,但是在使用上却是互各依赖。
第一个方法 hasNext() 方法用于验证迭代器中是否还有元素,如果还有元素则返回 true,否则返回 false
第二个方法 next() 方法用于获取迭代器的下一个元素,如果当前已经到达迭代器末尾,再次调用该方法就会抛出一个 NoSuchElementException 异常,因此我们可将此方法与之前的 hasNext() 方法结合使用,先判断是否拥有下一个元素,然后再获取元素,这样如果不存在下一个元素,就不再获取。
我们可以将 next() 方法想象成为一个指针,这个指针并不会指向具体的元素,而是指向元素与元素之间的间隙,初始时,该指针位于第一个元素之前的位置,调用 next() 一次,指针越过第一个元素,指向第一个元素与第二个元素的间隙,而该方法会将越过的元素返回。
第三个方法是 remove() 方法,用于移除集合中的刚刚被迭代器返回的元素,这个方法的使用是在第二个方法的基础上进行的,即需要先执行 next() 方法,然后再执行 remove() 方法,而且两个 remove 方法不能同时执行(即使是第一个元素的移除也要先执行 next 将第一个元素返回之后才能执行删除)
2.3 ListIterator 接口
ListIterator 是 Iterator 的子接口,在原来的基础上专门针对序列进行了扩展,其中定义了如下方法:
- boolean hasNext();
- E next();
- boolean hasPrevious();
- E previous();
- int nextIndex();
- int previousIndex();
- void remove();
- void set(E e);
- void add(E e);
第一个方法:同 Iterator
第二个方法:同 Iterator
第三个方法:hasPrevious() 用于反向遍历时查询是否还有剩余元素,作用同第一个方法,只是方向相反
第四个方法:previous() 用于获取反向查询时的下一个元素,越过下一元素并将该元素返回,作用同第二个方法,方向相反
第五个方法:nextIndex() 用于返回下一个位置,如果已到末尾,返回 list 的长度
第六个方法:previousIndex() 用于返回前一个位置,如果处于开始位置,返回 - 1
第七个方法:remove(),同 Iterator
第八个方法:set(E e) 用于替换最新返回的元素(可能是 next 方法返回的也可能是 previous 方法返回的)
第九个方法:add(E e) 用于插入新元素到当前序列的 next 或者 previous 将会返回的元素的前方 / 后方
2.4 Collection 接口
Collection 接口是单值集合的根接口,其中为这一类型的集合提供了基本的方法定义:
- int size();
- boolean isEmpty();
- boolean contains(Object o);
- Iterator iterator();
- Object[] toArray();
- T[] toArray(T[] a);
- boolean add(E e);
- boolean remove(Object o);
- boolean containsAll(Collection c);
- boolean addAll(Collectionextends E > c);
- boolean removeAll(Collection c);
- boolean retainAll(Collection c);
- void clear();
- boolean equals(Object o);
- int hashCode();
这里列出了 Collection 接口中定义的所有方法,共有 15 个:
第一个方法:size() 方法用于返回当前集合中元素的数量
第二个方法:isEmpty() 用于验证集合中是否包含元素,若包含元素则返回 false,若不包含元素则返回 true
第三种方法:contains(Object o) 验证集合中是否包含指定的元素,若包含则返回 true,否则返回 false
第四个方法:iterator() 用于返回基于当前集合的迭代器 Iterator
第五个方法:toArray() 用于获取包含当前集合中所有元素的数组,如果集合指定的顺序,那么数组的元素将按照这种顺序排列,并且这个数组将不再与集合有任何的联系,任何针对数组的修改都不会影响到集合。
第六个方法:toArray(T[] a) 用于获取包含当前集合中所有元素的数组,与上面的方法不同之处在于,此方法给定一个数组用于存放集合中的元素,若数组足够大能放得下所有的集合元素,则将数组剩余的位置置 null,若数组位数不足以保存所有的集合元素,则重新创建一个数组(这个数组与给定的数组的类型一致)来存放集合元素,第二种情况与上面的第五个方法情况相同。由于此方法给定了一个数组用来存放集合元素,因此效率比上面的略高。
第七个方法:add(E e) 用于在集合中添加新的元素,如果集合不允许重复元素且已存在该元素,则返回 false,如果集合结构发生了变化则返回 true(表示添加到集合中了)
第八个方法:remove(Object o) 用于移除集合中的某个元素,集合中删除元素会带来集合结构的部分变动。如果集合中包含该元素则返回 true
第九个方法:containsAll(Collection<?> c) 验证当前集合中是否包含给定集合中的所有元素,如果包含则返回 true,否则返回 false
第十个方法:addAll(Collection<? extends E> c) 用于将指定集合中的所有元素全部添加到当前集合中去,如果指定集合在添加过程中发生的变化则结果将变得不确定。
第十一个方法:removeAll(Collection<?> c) 用于移除当前集合中包含的指定集合中的所有元素,如果当前集合发生的改变则返回 true
第十二个方法:retainAll(Collection<?> c) 用于保留当前集合中同样在指定集合中存在的元素,移除所有不包含在指定集合中的元素,若集合发生的变化则返回 true
第十三个方法:clear() 用于移除当前集合中的所有元素,之后元素为 empty
第十四个方法:equals(Object o) 用于比较两个集合对象是否相同
第十五个方法:hashCode() 用于返回当前集合对象的 hash 值
2.5 List 接口
List 是一种有序集,又称序列。拥有下标,允许重复的值。其中定义了序列的一些专有的操作方法:
- E get(int index);
- E set(int index, E element);
- void add(int index, E element);
- E remove(int index);
- int indexOf(Object o);
- int lastIndexOf(Object o);
- ListIterator listIterator();
- ListIterator listIterator(int index);
- List subList(int fromIndex, int toIndex);
第一个方法:get(int index) 用于获取执行下标的元素
第二个方法:set(int index,E element) 用于设置执行下标的元素,替换指定位置的元素为给定的元素
第三个方法:add(int index, E element) 用于在指定位置插入新元素,其后的元素全部后移一位
第四个方法:remove(int index) 移除指定位置的元素,其后的元素全部前移一位
第五个方法:indexOf(Object o) 获取指定元素在序列中的位置(这里指的是第一次出现的位置),如果不存在则返回 - 1
第六个方法:lastIndexOf(Object o) 获取置顶元素在序列中的位置,方向为从末尾开始(反向)(第一次出现的位置),若不存在返回 - 1
第七个方法:listIterator() 获取一个基于序列中元素的序列迭代器
第八个方法:listIterator(int index) 获取一个基于序列中元素的序列迭代器,起始位置为指定的位置
第九个方法:subList(int fromIndex, int toIndex) 获取一个子序列,该子序列为截取自当前序列的指定开始位置到指定结束位置的序列段,如果开始位置 = 结束位置,则该子序列为 empty
2.6 Set 接口
查看源码可知 Set 接口与 Collection 接口中定义的方法完全一致,Set 集合表示的是无序的集合,其中不能有重复的元素。
2.7 Queue 接口
Queue 是队列接口,用于保存即将进行处理的元素,除了基本的 Collection 定义的方法之外,队列还提供了其他的插入、提取和移除操作。每个方法都存在两种形式:一种抛出异常(操作出错时),一种返回一个特殊值(null 或者 false),后面的这种操作是专门为拥有容量限制的 Queue 为设计的。
- boolean add(E e);
- boolean offer(E e);
- E remove();
- E poll();
- E element();
- E peek();
第一个方法:add(E e) 用于插入指定元素到队列中,如果不存在容量限制的情况下。如果执行成功返回 true,如果执行失败抛出 IllegalStateException 异常
第二个方法:offer(E e) 用于插入指定元素到队列中,如果不存在容量限制的情况下。当使用的是容量受限的队列,使用该方法将优于 add 方法。如果执行成功返回 true,否则返回 false。
第三个方法:remove() 用于移出队列顶部的元素,并将移除的元素返回,如果队列是空的,则会抛出一个 NoSuchElementException 异常
第四个方法:poll() 用于移除队列顶部的元素,并将移除的元素返回,如果队列是空的,则会返回 null
第五个方法:element(),获取队列顶部的元素(并不移除)如果队列为空,则抛出 NoSuchElementException 异常
第六个方法:peek() 获取队列顶部的元素(并不移除)如果队列为空,则返回 null
上面的方法来两两对应,分别用于应对两种不同的情况。
2.8 Map 接口
Map 是一种键值对集合,用于一对一的键值存储,键不能重复,值可以重复,一个键最多只能找到一个值。
Map 拥有三种集合视图:键集合(Set),值集合(Collection)、键值映射集合(Set)。
Map 集合的顺序被定义为其值集(Collection)的迭代器返回的顺序。
Map 集合的键一般使用不可变值,但是值可以使用易变值。因为可变的 key 可能会影响 equals 比较。
所有的 Map 集合的实现类都应该提供两个构造器:一个是无参构造器用于创建一个空的 Map 集合,一个是带 Map 集合参数的构造器,用于创建一个与给定集合一一对应的新的 Map 集合。
Map 集合中定义的方法如下:
- int size();
- boolean isEmpty();
- boolean containsKey(Object key);
- boolean containsValue(Object value);
- V get(Object key);
- V put(K key, V value);
- V remove(Object key);
- void putAll(Mapextends K, ?extends V > m);
- void clear();
- Set keySet();
- Collection values();
- Set > entrySet();
- boolean equals(Object o);
- int hashCode();
第一个方法:size() 用于返回 Map 集合中键值映射的数量
第二个方法:isEmpty() 用于验证集合中是否包含键值映射,如果没有表示集合是空的,返回 true,否则返回 false,表示集合非空
第三个方法:containsKey(Object key) 用于验证集合中是否包含指定的键的映射,如果包含返回 true,否则返回 false(验证集合中是否存在与指定的 key 相同的键的映射,如果指定的 key 是 null,则查找 null 为键的映射,否则查找与指定的 key 一致的键的映射)
第四个方法:containsValue(Object value) 用于验证集合中是否存在指定的值的映射(只可以重复,所以此处为至少存在一个),如果至少存在一个则返回 true,不存在返回 false
第五个方法:get(Object key) 用于获取集合映射中指定键的值,如果指定的键不存在则返回 null,否则返回对应的值。如果这个集合允许 null 值,那么返回 null 值就不确定是不存在映射还是存在映射,只是值为 null 的情况了,这时可以使用第三个方法来进行区分(通过 containsKey(Object key) 方法来验证指定的键是否存在,如果存在则返回的是正常保存的 null 值,否则返回的就是指不存在映射)
第六个方法:put(K key, V value) 用于将指定的映射保存到集合中去,如果指定的键已存在(键的存在性判断是通过 containsKey(Object key) 方法来判断的),则执行的是对应值的替换操作。
第七个方法:remove(Object key) 用于移除集合中指定键的映射,并将移除的映射的值返回,如果不存在指定键的映射,则返回 null,这对于允许 null 值的集合来说,又一次产生了歧义,解决方法同上。
第八个方法:putAll(Map<? extends K, ? extends V> m) 将指定的 map 集合中的所有映射拷贝到当前的 map 集合中去。
第九个方法:clear() 用于清空当前的 map 集合中的所有映射、
第十个方法:keySet() 返回 map 集合中的所有键的集合,这是一个 set 集合,这个集合就是 map 集合中键的映射,因此改变其中任何一项都可以在另一个里面发现这种改变。
第十一个方法:values() 用于获取 map 集合中包含的映射中的所有值的集合,这个集合是 map 集合中值的映射,因此改变其中任何一项都可以在另一个里面发现这种改变。
第十二个方法:entrySet() 用于获取 map 集合中包含的所有映射的集合,这是一个 set 集合,这个集合就是 map 集合中映射的映射,因此改变其中任何一项都可以在另一个里面发现这种改变。
2.9 Entry<K,V> 内部接口
该接口是在 Map 接口内部定义的,专门服务于 Map 集合,用于表示 Map 集合中的映射,映射表示的是键值对。
- K getKey();
- V getValue();
- V setValue(V value);
- boolean equals(Object o);
- int hashCode();
第一种方法:getKey() 方法用于获取键值映射中的键
第二种方法:getvalue() 方法用于获取键值映射中的值。
第三种方法:setValue(V value) 方法用于重置当前键值映射中的值
3、总结
上面的所有接口只是简单的对集合类型做了区分,划分了四类集合,分别为 Queue 队列,List 序列,Set 集,Map 映射集。并对每个类型的集合进行了简单的方法定义,用于确立此类集合的特点。Java 中针对每种集合都有多种实现用于应对不同的场景。
来源: http://www.cnblogs.com/V1haoge/p/7229478.html