集合
- 一、 迭代器模式(Iterator Pattern)
- 二、 工厂模式(Factory Pattern)
- 三、 装饰器模式(Decorator Pattern)
- 四、 适配器模式(Adapter Pattern)
- 五、 组合模式(Composite Pattern)
Java 集合框架中的 List、Set、Map 以及其实现类都使用了多种经典的设计模式
一、 迭代器模式(Iterator Pattern)
所有的集合接口(Collection、List、Set、Queue)和 Map 接口都定义了获取迭代器(Iterator)的方法,如 iterator()
、listIterator()
等。每个具体的集合实现类都提供了自己的迭代器实现,如 ArrayList 有 Itr
、LinkedList 有 ListItr
、HashMap 有 KeyIterator
和 ValueIterator
等。这些迭代器实现了 Iterator
接口,并对应集合的遍历算法。
以 ArrayList
为例,它的迭代器 Itr
实现如下:
private class Itr implements Iterator<E> {int cursor; // 下一个要访问的元素索引int lastRet = -1; // 最后一次返回的元素索引,方便删除操作// ...
}
二、 工厂模式(Factory Pattern)
Collections
工具类中的静态工厂方法(如 nCopies
、singletonList
、unmodifiableList
等)可以创建各种不同的集合实例。为了方便创建Map.Entry实例,Map接口提供了两个静态工厂方法SimpleEntry
和SimpleImmutableEntry
。这两个方法分别用来创建可变和不可变的Map.Entry实例。
public static <T> List<T> singletonList(T o) {return new ImmutableCollections.SetN<T>(o);
}
三、 装饰器模式(Decorator Pattern)
Collections
提供了一些修饰方法,用于对集合进行包装,如 synchronizedCollection
、unmodifiableCollection
等。这些方法使用了装饰器模式,在原有集合上添加了同步或只读等额外功能。
public static <T> List<T> synchronizedList(List<T> list) {return (list instanceof RandomAccess ?new SynchronizedRandomAccessList<>(list) :new SynchronizedList<>(list));
}static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> {// ...
}
四、 适配器模式(Adapter Pattern)
Arrays.asList
方法可以将数组转换为 List 集合,使用了适配器模式。EnumerationIterator
和 IteratorEnumeration
则用于在旧集合 Enumeration
和新集合 Iterator
之间进行适配。
public static <T> List<T> asList(T... a) {return new ArrayList<>(a);
}
五、 组合模式(Composite Pattern)
在Map接口中,每个Map.Entry对象表示了一个键值对(key-value pair),包含了一个键和一个值。通过这种组合结构,Map可以存储多个键值对,并提供了方便的方式来操作这些数据。在Map接口的实现类(如HashMap、TreeMap)中,每个键值对被表示为一个Map.Entry对象,通过Map的方法可以进行各种操作。组合模式允许将对象组合成树形结构,表示“部分-整体”的关系,在Map.Entry接口中,键和值构成了一个整体,即键值对的Entry,使得操作键值对变得简单方便。
- Map抽象接口内部定义了一个Entry接口,表示键值对。Entry接口包含了获取键、获取值、设置值、判断相等和获取哈希码等方法。
public interface Map<K, V> {// ...其他方法// 内部接口表示键值对interface Entry<K, V> {K getKey(); // 获取键V getValue(); // 获取值V setValue(V value); // 设置值,返回旧的值boolean equals(Object o); // 判断是否相等int hashCode(); // 获取哈希码}// ...其他方法
}
- 具体的Map实现类(如HashMap)的
Node 内部类
就是一个Entry
的实现,Node类实现了Map.Entry接口,表示了键值对信息。它包含了键、值和下一个节点的引用等信息
static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;V value;//下一个节点的引用等信息Node<K,V> next; // ...
}
在Java JDK 1.8中,AbstractMap 和 AbstractSet 等抽象类使用了组合模式。AbstractMap 是一个抽象类,它提供了Map接口的基本实现,并使用了组合模式来包装具体的 Map 实现。在 AbstractMap 中,最重要的部分是 entrySet() 方法,该方法返回一个Set<Entry<K,V>>类型的集合,表示 Map 的键值对集合。
public abstract class AbstractMap<K,V> implements Map<K,V> {// 返回一个包含所有 key-value 映射关系的 Set 集合public abstract Set<Entry<K,V>> entrySet();// 其他实现代码public static class SimpleEntry<K,V> implements Entry<K,V>, java.io.Serializable{private static final long serialVersionUID = -8499721149061103585L;private final K key;private V value;// 构造函数// 实现 equals()、hashCode() 等方法}
}
在 AbstractMap
中,entrySet() 方法返回的是一个 Set<Entry<K,V>>类型的集合。这里直接使用了 Java 中的 Entry 接口作为键值对的表示,而实际上 Entry 是一个内部接口,定义了对映射项(key-value 对)的操作。
AbstractMap 在内部使用了一个具体的实现类SimpleEntry
来表示键值对,但是对外部调用者来说,只需要知道 entrySet() 方法返回的是一个 Set<Entry<K,V>> 集合,而不需要关心具体的实现细节。
通过组合模式的设计,AbstractMap 实现了 Map 接口的基本功能,同时将具体的键值对信息封装在内部类中,加强了封装性和灵活性