第 8 章 Java的集合框架
2012-3-7 Java面向对象程序设计教程 2
主要内容
? 8.1 集合 API
? 8.2 Collection与 Iterator
? 8.2.1 Collection接口
? 8.2.2 迭代器 Iterator
? 8.3 List,LinkedList与 ArrayList
? 8.3.1 List接口
? 8.3.2 LinkedList与 ArrayList类
? 8.4 Set,SortedSet,HashSet与 TreeSet
? 8.4.1 Set和 SortedSet接口
? 8.4.2 HashSet,TreeSet和 LinkedHashSet类
? 8.5 Map,SortedMap接口及其实现类
? 8.5.1 Map接口
? 8.5.2 SortedMap接口
? 8.5.3 HashMap,TreeMap和 LinkedHashMap等实现类
8.1 集合 API
2012-3-7 Java面向对象程序设计教程 4
java.util包中的集合框架
2012-3-7 Java面向对象程序设计教程 5
java.util包中的主要接口
? Collection接口
集合的根接口。提供诸如 add,remove,size,toArray和 iterator等方法。
? Set接口
一个没有重复元素的集合,元素的存储没有任何特定的顺序,它扩展了 Collection接口,
使用自己内部的一个排列机制。
? SortedSet接口
扩展 Set接口,按元素排列到集合。
? List接口
扩展 Collection接口,允许重复,以元素安插的次序来放置元素,不会重新排列。
? Map接口
是一组成对的关键字-值( Key-value pairs)对象。 Map中不能有重复的关键字,它
拥有自己的内部排列机制,从关键字到至多一个对应值到映射。
? SortedMap接口
扩展 Map接口,按关键字排序到 Map。
? Iterator接口
用于对象到接口,这些对象每次从一个集合上返回一个元素。这是由 Collection接口的
iterator方法返回的对象的类型。
? ListIterator接口
List对象的 Iterator,这个对象加入了与 List相关的方法。这是由 List接口的
listIterator方法返回的对象类型。
2012-3-7 Java面向对象程序设计教程 6
java.util包中的主要类
? HashSet类
使用散列表实现的 Set,通常比较适用于那些对内容对规模比较敏感对搜索、插入、删
除等操作。
? TreeSet类
使用平衡二叉树实现的 SortedSet,搜索或者修改比 HashSet慢,但是它保持元素有
序。
? ArrayList类
使用可变数组实现等 List,如果列表比较大,那么,插入或者删除一个接近于开始处大
元素的代价将会很大,但是,创建的开销相对小一些,并且随机访问也会快一些。
? LinkedList类
一个实现 List的双向链表,在任何规模下,修改所花代价相当小,但是,随机访问是很
慢的。它对队列很有用。
? HashMap类
一个实现 Map对散列表,它是非常有用的集合,查询与插入所花时间比较少。
? TreeMap类
使用平衡二叉树,通过关键字保持元素有序的 SortedMap实现。对于那些需要通过关
键字进行快速查询的有序数据集有用。
? WeakHashMap类
通过弱引用对象引用关键字的实现 Map的散列表,它只在一些有限的情况下有用。
8.2 Collection与 Iterator
2012-3-7 Java面向对象程序设计教程 8
Collection接口
package java.util;
public interface Collection {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator iterator();
Object[] toArray();
Object[] toArray(Object a[]);
boolean add(Object o);
boolean remove(Object o);
boolean containsAll(Collection c);
boolean addAll(Collection c);
boolean removeAll(Collection c);
boolean retainAll(Collection c);
void clear();
boolean equals(Object o);
int hashCode();
}
2012-3-7 Java面向对象程序设计教程 9
单元素添加、删除操作
? boolean add(Object o)
先确定集合是否包含有对象 o,如果需要添加该对
象则返回 true。如果集合允许重复,add方法总
是返回 true。如果不允许重复,并已经有一个相
等的元素在集合中,则 add方法返回 false。
? boolean remove(Object o)
如果集合中有与 o相匹配的对象,则删除对象 o,
并返回 true;反之返回 false。如果 o为 null,并
且集合中也有一个元素为 null,也返回 true。
2012-3-7 Java面向对象程序设计教程 10
查询操作
? int size()
返回当前集合中元素的数量。
? boolean isEmpty()
判断集合中是否有任何元素。
? boolean contains(Object o)
查找集合中是否含有对象 o。
? Iterator iterator()
返回一个迭代器,用来访问集合中的各个
元素。
2012-3-7 Java面向对象程序设计教程 11
作用于元素组或整个集合的组操作
? boolean containsAll(Collection c)
查找集合中是否含有集合 c 中所有元素。
? boolean addAll(Collection c)
将集合 c 中所有元素添加给该集合。
? void removeAll(Collection c)
从集合中删除集合 c 中的所有元素。
? void retainAll(Collection c)
从集合中删除集合 c 中不包含的元素。
? void clear(),删除集合中所有元素。
2012-3-7 Java面向对象程序设计教程 12
Collection转换为 Object数组
? Object[] toArray()
返回一个内含集合所有元素的 Object类型
数组。
? Object[] toArray(Object[] a)
返回一个内含集合所有元素的 Object类型
数组。运行期返回的数组和参数 a的类型相
同,但使用时需要进行转换。
2012-3-7 Java面向对象程序设计教程 13
AbstractCollection抽象类
? AbstractCollection抽象类实现了 Collection接
口,提供具体集合框架类的基本功能。
? 除了 iterator和 size方法在恰当的子类中必须实现
( AbstractCollection类的抽象方法)以外,其
它所有方法都可利用 AbstractCollection 类来
提供实现。
? 如果子类不进行方法覆盖,已实现的 add方法将
引发异常 UnsupportedOperationException。
2012-3-7 Java面向对象程序设计教程 14
迭代器 Iterator
? Iterator接口方法能以迭代方式逐个访
问集合中各个元素,并安全的从
Collection中除去适当的元素。
package java.util;
public interface Iterator {
boolean hasNext();
Object next();
void remove();
}
? 举例,IteratorExample.java
? boolean hasNext()
判断是否存在另一个可访问的元素。
? Object next()
返回要访问的下一个元素。如果到达集
合结尾,则引发
NoSuchElementException异常。当
使用 next方法遍历元素时,如果需要,
可以接着使用 remove方法删除刚返回
的元素。 next和 hasNext方法是一种
健全的设计,能够以任何顺序调用它。
它们是相对独立的,可以多次调用
hasNext方法而不一定非要移到下一个
元素时再调用,并且会返回正确的答案。
? void remove()
删除上次访问返回的对象。本方法必须
紧跟在一个元素的访问后执行。如果上
次访问后集合已被修改,方法将引发
IllegalStateException异常。
8.3 List,LinkedList与 ArrayList
2012-3-7 Java面向对象程序设计教程 16
List接口
? List是链表的意思,也就
是数据对象会一个个串在
一起,所以存放在 List中
的数据是有特定顺序的。
? 存放在 List中的数据也是
可以重复的。
package java.util;
public interface List extends Collection {
//…… Collection已有的方法
//List增加的方法
boolean addAll(int index,Collection c);
Object get(int index);
Object set(int index,Object element);
void add(int index,Object element);
Object remove(int index);
int indexOf(Object o);
int lastIndexOf(Object o);
ListIterator listIterator();
ListIterator listIterator(int index);
List subList(int fromIndex,int toIndex);
}
2012-3-7 Java面向对象程序设计教程 17
面向位置的操作方法
? void add(int index,Object element)
在指定位置 index上添加元素 element
? boolean addAll(int index,Collection c)
将集合 c的所有元素添加到指定位置 index
? Object get(int index)
返回 List中指定位置的元素
? int indexOf(Object o)
返回第一个出现元素 o的位置,否则返回 -1
? int lastIndexOf(Object o)
返回最后一个出现元素 o的位置,否则返回 -1
? Object remove(int index)
删除指定位置上的元素
? Object set(int index,Object element)
用元素 element取代位置 index上的元素,并且返回旧的元素
2012-3-7 Java面向对象程序设计教程 18
处理集合的子集的方法
? ListIterator listIterator()
返回一个列表迭代器,用来访问列表中的元素
? ListIterator listIterator(int index)
返回一个列表迭代器,用来从指定位置 index开
始访问列表中的元素
? List subList(int fromIndex,int toIndex)
返回从指定位置 fromIndex(包含)到 toIndex
(不包含)范围中各个元素的子列表视图。对子
列表的更改(如 add,remove或 set调用)对底
层 List也有影响。
2012-3-7 Java面向对象程序设计教程 19
ListIterator接口
? ListIterator接口继承 Iterator
接口以支持添加或更改底层集
合中的元素,还支持双向访问。
? ListIterator没有当前位置,光
标位于调用 previous和 next方
法返回的值之间。
package java.util;
public interface ListIterator
extends Iterator {
//…… Iterator已有的方法
// ListIterator增加的方法
boolean hasPrevious();
Object previous();
int nextIndex();
int previousIndex();
void set(Object o);
void add(Object o);
}
ListIterator的索引位置示意
2012-3-7 Java面向对象程序设计教程 20
方法解释
? void add(Object o)
将对象 o添加到当前位置的前面。
? void set(Object o)
用对象 o替代 next或 previous方法访问的上一个元素。如果上次调用
后列表结构被修改了,那么将抛出 IllegalStateException异常。
? boolean hasPrevious()
判断向后迭代时是否有元素可访问。
? Object previous()
返回上一个对象。
? int nextIndex()
返回下次调用 next方法时将返回的元素的索引。
? int previousIndex()
返回下次调用 previous方法时将返回的元素的索引。
2012-3-7 Java面向对象程序设计教程 21
AbstractList和
AbstractSequentialList抽象类
? AbstractList和 AbstractSequentialList
是两个实现 List接口的抽象类。
? 它们覆盖了 equals和 hashCode方法以确
保两个相等的集合返回相同的散列码。
? 若两个列表大小相等且包含顺序相同的相
同元素,则这两个列表相等。
2012-3-7 Java面向对象程序设计教程 22
LinkedList与 ArrayList类
? ArrayList和 LinkedList是 List接口的两种
常规实现
? 如果要支持随机访问,而不仅在除尾部的
任何位置插入或除去元素,那么,
ArrayList 提供了可选的集合。
? 如果我们不要频繁的从列表的中间位置添
加和除去元素,而只要顺序的访问列表元
素,那么,LinkedList 实现更好。
? 例子,ListExample.java
8.4 Set,SortedSet,HashSet与 TreeSet
2012-3-7 Java面向对象程序设计教程 24
Set接口
? Set接口继承 Collection接口,而且它不允
许集合中存在重复项,每个具体的 Set实现
类依赖添加的对象的 equals方法来检查唯
一性。
? Set接口没有引入新方法,所以 Set就是一
个 Collection,只不过其行为不同。
2012-3-7 Java面向对象程序设计教程 25
SortedSet接口
? SortedSet是扩展了 Set的一个特殊接口,
它保持元素的有序顺序。
? SortedSet接口为集的视图(子集)和它
的两端(即头和尾)提供了访问方法。
? 添加到 SortedSet实现类的元素必须实现
Comparable接口,否则我们必须给它的
构造方法提供一个 Comparator接口的实
现。 TreeSet类是它的唯一一份实现。
2012-3-7 Java面向对象程序设计教程 26
AbstractSet抽象类
? AbstractSet类覆盖了 Object类的 equals
和 hashCode方法,以确保两个相等的集返
回相同的散列码。
? 若两个集大小相等且包含相同元素,则这
两个集相等。
? 按定义,集的散列码是集中元素散列码的
总和。因此,不论集的内部顺序如何,两
个相等的集会有相同的散列码。
2012-3-7 Java面向对象程序设计教程 27
HashSet,TreeSet和
LinkedHashSet类
? HashSet和 TreeSet类是支持 Set接口两种普通
的实现,TreeSet类实现了 SortedSet接口。
? 在更多情况下,我们会使用 HashSet存储重复自
由的集合。
? 当我们要从集合中以有序的方式插入和抽取元素
时,TreeSet实现会有用处。为了能顺利进行,
添加到 TreeSet的元素必须是可排序的。
? 例子,SetExample.java
8.5 Map,SortedMap接口及其实现类
2012-3-7 Java面向对象程序设计教程 29
Map接口
? Map接口不是 Collection
接口的继承。
? Map接口用于维护关键字
-值对 (key-value
pairs)。描述了从不重复
的关键字到值的映射。
package java.util;
public interface Map {
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
Object get(Object key);
Object put(Object key,Object value);
Object remove(Object key);
void putAll(Map t);
void clear();
Set keySet();
Collection values();
Set entrySet();
interface Entry {
Object getKey();
Object getValue();
Object setValue(Object value);
boolean equals(Object o);
int hashCode();
}
boolean equals(Object o);
int hashCode();
}
2012-3-7 Java面向对象程序设计教程 30
添加、删除操作
? Object put(Object key,Object value)
将互相关联的一个关键字与一个值放入该映射。如果该关
键字已经存在,那么与此关键字相关的新值将取代旧值。
方法返回关键字的旧值,如果关键字原先并不存在,则返
回 null。
? Object remove(Object key)
从映射中删除与 key相关的映射。
? void putAll(Map t)
将来自特定映射的所有元素添加给该映射。
? void clear()
从映射中删除所有映射关键字-值都可以为 null。但是,
我们不能把 Map作为一个关键字或值添加给自身。
2012-3-7 Java面向对象程序设计教程 31
查询操作
? Object get(Object key)
获得与关键字 key相关的值,并且返回与关键字
key相关的对象,如果没有在该映射中找到该关
键字,则返回 null。
? boolean containsKey(Object key)
判断映射中是否存在关键字 key。
? boolean containsValue(Object value)
判断映射中是否存在值 value。
? int size()
返回当前映射中映射的数量。
? boolean isEmpty()
判断映射中是否有任何映射。
2012-3-7 Java面向对象程序设计教程 32
处理映射中关键字-值对的视图操作
? Set keySet()
返回映射中所有关键字的视图集。因为映射中关键字的集合必须是唯 一的,可用 Set支持。我们还可以从视图中删除元素,同时,关键字
和它相关的值将从源映射中被删除,但是我们不能添加任何元素。
? Collection values()
返回映射中所有值的视图集。因为映射中值的集合不是唯一的,可用 Collection支持。我们还可以从视图中删除元素,同时,值和它的关
键字将从源映射中被删除,但是我们不能添加任何元素。
? Set entrySet()
返回 Map.Entry对象的视图集,即映射中的关键字-值对。因为映射
是唯一的,可用 Set支持。我们还可以从视图中删除元素,同时,这
些元素将从源映射中被删除,但是我们不能添加任何元素。
2012-3-7 Java面向对象程序设计教程 33
Map.Entry接口
? 通过这个集合的迭代
器,我们可以获得每
一个条目(唯一获取
方式)的关键字或值
并对值进行更改。
? Map.Entry接口的方
法有,
? Object getKey()
返回条目的关键字。
? Object getValue()
返回条目的值。
? Object setValue(Object
value)
将相关映射中的值改为
value,并且返回旧值。
2012-3-7 Java面向对象程序设计教程 34
SortedMap接口
? SortedMap是 Map的特殊的接
口,它用来保持关键字的有序
顺序。
? SortedMap接口为映射的视图
(子集),包括两个端点提供
了访问方法。除了排序是作用
于映射的关键字以外,处理
SortedMap和处理 SortedSet
一样。
? 添加到 SortedMap实现类的元
素必须实现 Comparable接口,
否则我们必须给它的构造方法
提供一个 Comparator接口的
实现。
package java.util;
public interface SortedMap
extends Map {
Comparator comparator();
SortedMap subMap(Object
fromKey,Object toKey);
SortedMap
headMap(Object toKey);
SortedMap tailMap(Object
fromKey);
Object firstKey();
Object lastKey();
}
2012-3-7 Java面向对象程序设计教程 35
方法解释
? Comparator comparator()
返回对关键字进行排序时使用的比较器,如果使用 Comparable接口
的 compareTo方法对关键字进行比较,则返回 null。
? Object firstKey()
返回映射中第一个(最低)关键字。
? Object lastKey()
返回映射中最后一个(最高)关键字。
? SortedMap subMap(Object fromKey,Object toKey)
返回从 fromKey(包含)至 toKey(不包含)范围内元素的
SortedMap视图(子集)。
? SortedMap headMap(Object toKey)
返回 SortedMap的一个视图,其内各元素的 key皆小于 toKey。
? SortedSet tailMap(Object fromKey)
返回 SortedMap的一个视图,其内各元素的 key皆大于或等于
fromKey。
2012-3-7 Java面向对象程序设计教程 36
HashMap,TreeMap等实现类
? HashMap和 TreeMap类是 Map接口的两种常规
实现,TreeMap实现 SortedMap接口。
? 在 Map中插入、删除和定位元素,HashMap是最
好的选择。
? 如果我们要按自然顺序或自定义顺序遍历关键字,
那么 TreeMap会更好。
? 使用 HashMap要求添加的关键字类明确定义了
hashCode和 equals方法的实现。
? 例子,MapExample.java