Java源码分析 – 策略模式在Java集合框架实现代码中的体现
本文由发表于6年前 | Java基础 | 评论数 4 |  被围观 8,972 views+

在Java的集合框架中,构造Map或者Set时传入Comparator比较器,或者创建比较器传入Collections类的静态方法中作为方法的参数为Collection排序时,都使用到了策略模式

下面就以创建比较器传入Collections类的静态方法为例说明,下面是简单的调用代码:
LinkedList<String> list = new LinkedList<String>();
list.add("arthinking");
list.add("Jason");
list.add("X");
//创建一个逆序的比较器
Comparator<String> r = Collections.reverseOrder();
//通过逆序的比较器进行排序
Collections.sort(list,r);

使用Collections.reverseOrder()方法床架一个比较器之后,再调用Collections.sort(list, r)把比较器传入该方法中进行排序,下面就看一下sort(list, r)中的代码:

public static <T> void sort(List<T> list, Comparator<? super T> c) {
	Object[] a = list.toArray();
	Arrays.sort(a, (Comparator)c);
	ListIterator i = list.listIterator();
	for (int j=0; j<a.length; j++) {
	    i.next();
	    i.set(a[j]);
	}
}

Arrays.sort(a, (Comparator)c);这句继续把比较器传入处理,下面是Arrays.sort(a, (Comparator)c)的具体操作:

public static <T> void sort(T[] a, Comparator<? super T> c) {
	T[] aux = (T[])a.clone();
        if (c==null)
            mergeSort(aux, a, 0, a.length, 0);
        else
            mergeSort(aux, a, 0, a.length, 0, c);
}

这里又调用了mergeSort(aux, a, 0, a.length, 0, c);继续传递比较器,再跟进去,发现如下执行代码:

private static void mergeSort(Object[] src,
				  Object[] dest,
				  int low, int high, int off,
				  Comparator c) {
	int length = high - low;

	// Insertion sort on smallest arrays
	if (length < INSERTIONSORT_THRESHOLD) {
	    for (int i=low; i<high; i++)
		for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
		    swap(dest, j, j-1);
	    return;
	}

        // Recursively sort halves of dest into src
        int destLow  = low;
        int destHigh = high;
        low  += off;
        high += off;
        int mid = (low + high) >>> 1;
        mergeSort(dest, src, low, mid, -off, c);
        mergeSort(dest, src, mid, high, -off, c);

        // If list is already sorted, just copy from src to dest.  This is an
        // optimization that results in faster sorts for nearly ordered lists.
        if (c.compare(src[mid-1], src[mid]) <= 0) {
           System.arraycopy(src, low, dest, destLow, length);
           return;
        }

        // Merge sorted halves (now in src) into dest
        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
            if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
                dest[i] = src[p++];
            else
                dest[i] = src[q++];
        }
}

这段代码有点复杂,我们跳出其中使用到比较器的代码分析:

c.compare(dest[j-1], dest[j])>0;

这里的compare方法在Comparator接口中也有定义:

public interface Comparator<T> {
    int compare(T o1, T o2);
}

由于这里使用泛型实现了Comparator,所以实际执行时,会根据比较器的具体实现类调用到实现代码,也就是上面创建的逆序比较器的compare方法,其实现如下:

public int compare(Comparable<Object> c1, Comparable<Object> c2) {
     return c2.compareTo(c1);
}
从上面的跟踪代码执行流程,可以得出:

抽象策略角色类为:Comparator接口
真实策略角色类为:ReverseComparator
我们在这里传入不同的比较器就会得到不同的排序的执行方法了:

Collections.sort(list,r);
除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/java-source-code-analysis-strategy-pattern-implementation-in-java-collections-framework-embodied-in-the-code.html
arthinking Java技术交流群:280755654,入门群:428693174 more
分享到:
 
2011 10/17
文章评论
    4条评论
  1. 桃华月禅 2014年05月17日18:46:08  #-49楼 回复 回复

    受教了,看Head first第一章学到的策略这模式没想到过去自己竟然用过?那么beanUtil中传入日期转换器也是策略者模式?还有什么事件监听器,xml解析处理器都是策略者模式吗?

    • 包小卷 2014年05月17日19:31:44 回复 回复

      事件监听器观察者模式,很多设计模式不用刻意去学习的,查看到一些优秀源代码的实现的时候,不经意就发现用上了一些所谓的设计模式。

      • 桃华月禅 2014年05月17日20:15:45 回复 回复

        原来如此,正在学习编程,感觉你写的博客有很多值得看的知识。持续关注你的博客^_^

给我留言

有人回复时邮件通知我
Java基础的相关文章
随机文章 本月热门 热评
1 Hibernate一对一唯一外键关联映射的实现方法实例 2011/9/4
2 org.apache.el.parser.ParseException JSTL中EL表达式错误提示 2011/7/30
3 【吉他曲子学习资源】Kotaro Oshio: wings you are the hero 2012/1/2
4 数据结构笔记 – 排序算法 优化冒泡排序算法 2011/9/20
5 数据结构笔记 – 栈与队列 递归的使用 2011/10/21
6 8251A串行通信和8253计数器编程举例 2011/5/5
友情推荐 更多
破博客 文官洗碗安天下,武将打怪定乾坤。多么美好的年代,思之令人泪落。
Mr.5's Life 白天是一名程序员,晚上就是个有抱负的探索者
行知-追寻技术之美 关注大数据,分布式系统
我爱编程 编程成长轨迹
Cynthia's Blog 学习笔记 知识总结 思考感悟
 
猜您喜欢
欢迎关注我的公众号 IT宅
关于IT宅 文章归档

IT宅中的文章除了标题注明转载或有特别说明的文章,均为IT宅的技术知识总结,学习笔记或随笔。如果喜欢,请使用文章下面提供的分享组件。转载请注明出处并加入文章的原链接。 感谢大家的支持。

联系我们:admin@itzhai.com

Theme by arthinking. Copyright © 2011-2015 IT宅.com 保留所有权利.