Java集合中经典的 5种设计模式,打死也要记住啊!


Java 集合框架中的 List、Set、Map 以及其实现类都使用了多种经典的设计模式

一、 迭代器模式(Iterator Pattern)

所有的集合接口(Collection、List、Set、Queue)和 Map 接口都定义了获取迭代器(Iterator)的方法,如 iterator()listIterator()等。每个具体的集合实现类都提供了自己的迭代器实现,如 ArrayList 有 Itr、LinkedList 有 ListItr、HashMap 有 KeyIteratorValueIterator 等。这些迭代器实现了 Iterator 接口,并对应集合的遍历算法。

ArrayList 为例,它的迭代器 Itr 实现如下:

private class Itr implements Iterator<E> {
    int cursor;       // 下一个要访问的元素索引
    int lastRet = -1; // 最后一次返回的元素索引,方便删除操作
    // ...
}

在这里插入图片描述

二、 工厂模式(Factory Pattern)

Collections 工具类中的静态工厂方法(如 nCopiessingletonListunmodifiableList 等)可以创建各种不同的集合实例。为了方便创建Map.Entry实例,Map接口提供了两个静态工厂方法SimpleEntrySimpleImmutableEntry。这两个方法分别用来创建可变和不可变的Map.Entry实例。

public static <T> List<T> singletonList(T o) {
    return new ImmutableCollections.SetN<T>(o);
}

三、 装饰器模式(Decorator Pattern)

Collections 提供了一些修饰方法,用于对集合进行包装,如 synchronizedCollectionunmodifiableCollection 等。这些方法使用了装饰器模式,在原有集合上添加了同步或只读等额外功能。

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 集合,使用了适配器模式。EnumerationIteratorIteratorEnumeration 则用于在旧集合 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 接口的基本功能,同时将具体的键值对信息封装在内部类中,加强了封装性和灵活性

  • 24
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java语录精选

你的鼓励是我坚持下去的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值