在 Java 2 之前,Java 提供了一些临时性的类如 Dictionary、Vector、Stack 和 Properties 来存储和操作对象组。尽管这些类非常有用,但它们缺乏一个中心统一的主题。因此,使用 Vector 的方式与使用 Properties 的方式不同。
为什么使用集合框架?
集合框架的设计是为了满足几个目标,例如:
-
框架必须具有高性能。基础集合(动态数组、链表、树和哈希表)的实现应当高效。
-
框架必须允许不同类型集合以类似的方式工作,并具有高度的互操作性。
-
为了达到这些目的,整个集合框架都是围绕一系列标准接口设计的。提供了一些标准实现如 LinkedList、HashSet 和 TreeSet,您可以直接使用这些实现,也可以选择自己实现集合。
Java 集合框架
集合框架是一种表示和操作集合的统一架构。所有集合框架都包含以下内容:
-
接口 — 这些是抽象数据类型,表示集合。接口允许独立于其实现细节来操纵集合。在面向对象语言中,接口通常形成一个层次结构。
-
实现,即类 — 这些是集合接口的具体实现。本质上,它们是可重用的数据结构。
-
算法 — 这些是对实现了集合接口的对象执行有用计算(如搜索和排序)的方法。算法被认为是多态的:也就是说,相同的方法可以用于许多不同的适当集合接口实现。
除了集合外,框架还定义了几种映射接口和类。映射存储键/值对。虽然严格意义上来说映射不是集合,但它们与集合完全集成。
集合框架层次结构
所有集合框架的类和接口都存在于 java.utli
包中。下图显示了 Java 中集合框架的层次结构:
Java 集合接口
集合框架定义了几个接口。本节提供每个接口的概述:
序号 |
接口 & 描述 |
1 |
Collection 接口 使您能够处理对象组;它是集合层次结构的顶部。 |
2 |
List 接口 扩展 Collection,实例化 List 存储有序的元素集合。 |
3 |
Set 扩展 Collection 以处理集合并必须包含唯一元素。 |
4 |
SortedSet 扩展 Set 以处理排序集。 |
5 |
Map 将唯一键映射到值。 |
6 |
Map.Entry 描述映射中的元素(键/值对)。这是 Map 的内部类。 |
7 |
SortedMap 扩展 Map 以便维护键的升序。 |
8 |
Enumeration 这是遗留接口定义了枚举(一次获取一个)集合中的元素的方法。此遗留接口已被 Iterator 取代。 |
Java 集合类
Java 提供了一组标准集合类,实现了集合接口。某些类提供了完整的实现可以直接使用,而另一些则是抽象类,提供了骨架实现,可以用作创建具体集合的起点。
标准集合类在下表中进行了总结:
序号 |
类 & 描述 |
1 |
AbstractCollection 实现了大部分 Collection 接口。 |
2 |
AbstractList 扩展 AbstractCollection 并实现了大部分 List 接口。 |
3 |
AbstractSequentialList 扩展 AbstractList 用于使用顺序而不是随机访问其元素的集合。 |
4 |
LinkedList 通过扩展 AbstractSequentialList 实现链表。 |
5 |
ArrayList 通过扩展 AbstractList 实现动态数组。 |
6 |
AbstractSet 扩展 AbstractCollection 并实现了大部分 Set 接口。 |
7 |
HashSet 扩展 AbstractSet 以使用散列表。 |
8 |
LinkedHashSet 扩展 HashSet 允许插入顺序迭代。 |
9 |
TreeSet 实现在树中存储的集合。扩展 AbstractSet。 |
10 |
AbstractMap 实现了大部分 Map 接口。 |
11 |
HashMap 扩展 AbstractMap 使用散列表。 |
12 |
TreeMap 扩展 AbstractMap 使用树。 |
13 |
WeakHashMap 扩展 AbstractMap 使用弱键的散列表。 |
14 |
LinkedHashMap 扩展 HashMap 允许插入顺序迭代。 |
15 |
IdentityHashMap 扩展 AbstractMap 在比较文档时使用引用相等性。 |
AbstractCollection
、AbstractSet
、AbstractList
、AbstractSequentialList
和 AbstractMap
类提供了核心集合接口的骨架实现,以尽量减少实现它们所需的努力。
以下是一些 java.util
包中定义的遗留类:
序号 |
类 & 描述 |
1 |
Vector 实现动态数组。类似于 ArrayList,但有一些差异。 |
2 |
Stack Stack 是 Vector 的子类,实现了标准的后进先出栈。 |
3 |
Dictionary Dictionary 是一个抽象类,表示键/值存储库,其操作类似于 Map。 |
4 |
Hashtable 是原始 java.util 包的一部分,是 Dictionary 的具体实现。 |
5 |
Properties 是 Hashtable 的子类,用于维护键为字符串且值也为字符串的值列表。 |
6 |
PriorityQueue PriorityQueue 类是一个基于优先级堆的无界优先队列。依赖自然排序的优先队列也不允许插入不可比较的对象。 |
7 |
BitSet BitSet 类创建一种特殊类型的数组,持有位值。此数组可以根据需要增长。 |
8 |
ArrayDeque ArrayDeque 类提供可调整大小的数组并实现了 Deque 接口。数组双端队列没有容量限制,因此可以根据需要增长。 |
9 |
EnumMap EnumMap 类是专门用于使用枚举键的 Map 实现。所有 EnumMap 的键必须来自创建时显式或隐式指定的单个枚举类型。 |
10 |
Queue
java.util 包中提供的队列接口实现了 Collection 接口。队列实现了 FIFO 即先进先出。这意味着首先进入的元素也是首先被删除的。 |
11 |
Deque EnumMap 类是专门用于使用枚举键的 Map 实现。所有 EnumMap 的键必须来自创建时显式或隐式指定的单个枚举类型。 |
集合算法
集合框架定义了几种可以应用于集合和映射的算法。这些算法定义为 Collections
类中的静态方法。
一些方法可能会抛出 ClassCastException
,当尝试比较不兼容的类型时发生,或者抛出 UnsupportedOperationException
,当尝试修改不可修改的集合时发生。
集合定义了三个静态变量:EMPTY_SET
、EMPTY_LIST
和 EMPTY_MAP
。所有都是不可变的。
序号 |
算法 & 描述 |
1 |
集合算法 以下是所有算法实现的列表。 |
如何使用迭代器?
通常情况下,您希望遍历集合中的元素。例如,您可能想要显示每个元素。
最简单的方法是使用迭代器,这是一个实现了 Iterator 或 ListIterator 接口的对象。
迭代器使您能够在集合中循环,获取或移除元素。ListIterator 扩展了 Iterator,以允许双向遍历列表以及修改元素。
序号 |
迭代器方法 & 描述 |
1 |
使用 Java Iterator 以下是 Iterator 和 ListIterator 接口提供的所有方法及其示例的列表。 |
如何使用 Comparator?
TreeSet 和 TreeMap 将元素存储在排序顺序中。然而,正是比较器定义了确切的排序顺序。
这个接口让我们可以按照任意数量的不同方式对给定集合进行排序。此外,此接口可用于排序任何类的实例(即使是我们无法修改的类)。
序号 |
迭代器方法 & 描述 |
1 |
使用 Java Comparator 以下是 Comparator 接口提供的所有方法及其示例的列表。 |
如何使用 Comparable?
TreeSet 和 TreeMap 将元素存储在排序顺序中。我们可以使用 Comparable 接口来定义确切的排序顺序。
这个接口让我们可以按照任意数量的不同方式对给定集合进行排序。此外,此接口可用于排序任何类的实例(即使是我们无法修改的类)。
序号 |
迭代器方法 & 描述 |
1 |
使用 Java Comparable 以下是 Comparable 接口提供的所有方法及其示例的列表。 |
总结
Java 集合框架为程序员提供了预包装的数据结构以及操作这些数据结构的算法。
集合是一个可以保存对其他对象引用的对象。集合接口声明了可以对每种类型的集合执行的操作。
集合框架的类和接口位于 java.util
包中。