9.1 Java Collections框架
前言
Java 最初版本只为最常用的数据结构提供了很少的一组类:Vector、Stack、HashtableBitSet 与Enumeration 接口, 其中的Enumeration 接口提供了一种用于访问任意容器中各个元素的抽象机制。这是一种很明智的选择,但要想建立一个全面的集合类库还需要大量的时间和高超的技能。
9.1.1分离收集接口和实现
与现代数据结构库一样,Java集合库将接口和实现分开。让我们用熟悉的数据结构queue来看看这种分离。
(1)一个队列接口指定:
- 在队列的末尾添加元素,在头部删除它们
- 当需要收集对象并以“先进先出”的方式检索对象时,可以使用队列
(2)队列接口的最简形式可能类似下面这样
public interface Queue <E> //标准库中接口的简化形式
{
void add(E element);
E remove();
int size();
}
该界面并没有告诉我们如何实现队列的任何信息,只提供了一个接口。其实队列通常有两种实现方式。
(3)队列的两种常见实现方式
- 使用循环数组
- 使用链表
每一个实现都可以通过一个实现了Queue接口的类表示:
public class CircularArrayQueue<E> implements Queue<E> // not an actual library class
{
private int head;
private int tail;
CircularArrayQueue(int capacity) { . . . }
public void add(E element) { . . . }
public E remove() { . . . }
public int size() { . . . }
private E[] elements;
}
public class LinkedListQueue<E> implements Queue<E> // not an actual library class
{
private Link head;
private Link tail;
LinkedListQueue() { . . . }
public void add(E element) { . . . }
public E remove() { . . . }
public int size() { . . . }
}
- 注意:
实际上,Java 类库没有名为CircularArrayQueue LinkedListQueue 的类。这里,只是以这些类作为示例, 解释一下集合接口与实现在概念上的不同。如果需要一个循环数组队列, 就可以使用ArrayDeque 类。如果需要一个链表队列, 就直接使用LinkedList类, 这个类实现了Queue 接口。
(4)当我们在程序中使用Queue时,一旦构造了集合,就无需知道实际使用了哪种实现。因此,只有在构造收集对象时才使用具体的类。使用接口类型来保存集合引用。
Queue<Customer> expressLane = new CircularArrayQueue<>(100);
expressLane.add(new Customer("Harry"));
通过这种方法,如果您改变主意,则可以轻松使用其他实现。您只需要在构造函数调用中的一个地方更改程序即可。如果您认为LinkedListQueue毕竟是一个更好的选择,那么您的代码将变为
Queue <Customer> expressLane = new LinkedListQueue <>();
expressLane.add(new Customer(“ Harry”));
为什么要选择一种实现而不是另一种实现?该界面没有说明实现的效率。
- 循环数组比链表更有效率,因此通常是可取的。但是,像往常一样,需要付出一定的代价。
- 循环数组是有界的,它具有有限的容量。如果程序中要收集的对象数量没有上限, 就最好使用链表来实现
总结
♥这个相对于之前的博客来说内容更加详细,后续会继续更新♥