﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Jerome Kwok〖旧日的足迹〗-文章分类-Java SE</title><link>http://www.blogjava.net/JeromeKwok/category/43883.html</link><description>仁者不忧，知者不惑，勇者不惧</description><language>zh-cn</language><lastBuildDate>Sat, 08 Dec 2012 12:29:09 GMT</lastBuildDate><pubDate>Sat, 08 Dec 2012 12:29:09 GMT</pubDate><ttl>60</ttl><item><title>java日期操作</title><link>http://www.blogjava.net/JeromeKwok/articles/391749.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 22 Nov 2012 04:25:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/391749.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;只有注册用户登录后才能阅读该文。<a href='http://www.blogjava.net/JeromeKwok/articles/391749.html'>阅读全文</a><img src ="http://www.blogjava.net/JeromeKwok/aggbug/391749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2012-11-22 12:25 <a href="http://www.blogjava.net/JeromeKwok/articles/391749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]关于 Java Collections API 您不知道的 5 件事，第 1 部分</title><link>http://www.blogjava.net/JeromeKwok/articles/339892.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Mon, 06 Dec 2010 03:38:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/339892.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/339892.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/339892.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/339892.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/339892.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;只有注册用户登录后才能阅读该文。<a href='http://www.blogjava.net/JeromeKwok/articles/339892.html'>阅读全文</a><img src ="http://www.blogjava.net/JeromeKwok/aggbug/339892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-12-06 11:38 <a href="http://www.blogjava.net/JeromeKwok/articles/339892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]关于 Java Collections API 您不知道的 5 件事，第 2 部分</title><link>http://www.blogjava.net/JeromeKwok/articles/339891.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Mon, 06 Dec 2010 03:33:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/339891.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/339891.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/339891.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/339891.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/339891.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;只有注册用户登录后才能阅读该文。<a href='http://www.blogjava.net/JeromeKwok/articles/339891.html'>阅读全文</a><img src ="http://www.blogjava.net/JeromeKwok/aggbug/339891.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-12-06 11:33 <a href="http://www.blogjava.net/JeromeKwok/articles/339891.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于集合框架的思考</title><link>http://www.blogjava.net/JeromeKwok/articles/339888.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Mon, 06 Dec 2010 03:14:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/339888.html</guid><description><![CDATA[<dl>
<dt>
<p><span style="font-family: Courier"><span style="font-size: 12pt"><span style="font-size: 14pt"><span style="font-size: 10pt"><span style="font-size: 12pt"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-size: 10pt"><span style="font-size: 12pt"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-size: 12pt"><span style="font-size: 10pt"><span style="font-family: Comic Sans MS"><span style="font-size: 12pt"><span style="font-family: 微软雅黑"><span style="font-size: 10pt">&nbsp;</p>
<p><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">对于Java集合框架（Java Collections Framework，JCF），Java玩家大概都不会陌生，在C++里面相似的概念是标准模板库（Standard Template Library，STL），<br />
</p>
主要是对一些数据结构和相关算法的封装。考虑到这是一个Java初学者将会经常接触的工具，所以有了以下的一些文字。主要是参考了IBM developerWorks上的一篇<br />
教程，它可能解释得更加清晰，这里算是浓缩了一下吧，真正的来龙去脉可以看看JDK文档里的&#8220;The Collections Framework&#8221;，说明更为详细。 <br />
问题的源头</span></span></span></span></span></span></span></span></span></span></span></span></span>
<pre><br />
<span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&#8226;集合：对象的容器与数据结构<br />
&nbsp;&nbsp;&nbsp; 回忆一下我们在程序设计里头可能会面对一些什么，无非是两类：基本类型和复合类型，后者常见的组织方式就是类。和基本类型不同，类对象通常是需要以动态方<br />
式分配的，譬如在内存的堆空间里new一个对象，这个我们一写OO的程序就必然会用到。同时我们面对的不仅仅是单个的基本类型或对象，对多个这样的数据我们通常<br />
采用的组织方式是什么？不错，是数组，这是伴随程序设计的一个古老概念。数组的优点显而易见，像根据下标检索元素这样的操作不费吹灰之力，但缺点也很明显：<br />
空间固定而不能动态增长（像Java这样的强类型语言对数组越界是及其敏感的），插入或删除元素比较费劲。因此数组不是解决一切集合问题的方便工具。我们可能需要<br />
一些新的工具，研究这些工具常常就是研究数据结构，特别的，数组本身就是一种线性有序的数据结构。<br />
&nbsp;&nbsp;&nbsp; 数据结构的数学基础是集合论，为什么这么说呢？上面说过，现在我们要研究的不是单个的基本类型或对象，多个对象的整体不就是集合吗？从OO的角度上看，集合<br />
也是一种对象，但它是一种特殊的对象：对象的容器（注意，我们这里没有继续讨论基本类型的集合，因为基本类型和存储分配方式与对象有着本质的差别）。集合论的<br />
一个根本问题就是：给定一个元素，集合必须能够回答该元素是或者不是属于这个集合。还有一个问题也很重要，就是：如果元素是属于一个集合，那该元素在集合中的<br />
地位应该是唯一的，或者说它是唯一确定的。当然还有其它问题，譬如查找、遍历、排序等等，这和具体的集合类型相关，后面将会讲到。 <br />
&#8226;无序集、有序集、映射<br />
&nbsp;&nbsp;&nbsp; 谈到集合的类型，我们在高中所学的集合概念是其中的一种，叫做&#8220;无序集&#8221;，也就是说集合的各个元素都是平等的，没有先后的区别，于是在无序集当中就决不允<br />
许出现一模一样的元素，否则当取到这个元素的时候就不知道应该取哪一个，这就违反了上面的&#8220;唯一确定&#8221;原则。<br />
&nbsp;&nbsp;&nbsp; 等到我们上了大学，开始知道了另一种集合类型，叫做&#8220;有序集&#8221;（或者叫&#8220;线性表&#8221;，区别于以后碰到的像&#8220;树&#8221;，&#8220;图&#8221;这样的非线性的数据结构），如果是计<br />
算机专业的，大概学过离散数学当中的&#8220;代数结构&#8221;，那你就更清楚的知道，&#8220;有序集&#8221;其实是一种&#8220;二元关系&#8221;，确切的说是&#8220;偏序关系&#8221;，它是可以包含相同元素<br />
的，因为两个的相同元素的&#8220;序号&#8221;可以不同，这样根据&#8220;序号&#8221;仍可以&#8220;唯一确定&#8221;一个元素，数组就是一种有序集，有序集的另一个特点就是任意两个元素可以确<br />
定他们的顺序。<br />
&nbsp;&nbsp;&nbsp; 无序集，有序集，难道还有第三种可能？呵呵，它还是出现在我们的高中代数课本里，叫做&#8220;映射&#8221;。映射也是集合？其实自从康托尔以来，集合论就认为&#8220;万物皆<br />
集合&#8221;（但也就是这个断言导致了集合论以后的尴尬境地，有兴趣可以看看罗素或哥德尔的一些结论，或google&#8220;集合论 悖论&#8221;）。映射其实是一种&#8220;元素对&#8221;的集合<br />
，就像f(a)=b, f(c)=d, ...等效于集合（无序集）{(a, b), (c, d), ...}，在&#8220;映射&#8221;中可以看作是(原象, 象)的集合，换一种说法就是(关键字key, 值value)的集合。所以我们可<br />
以在笛卡儿正交坐标平面上画出漂亮的函数图像，因为在集合论看来，函数（映射）就是二维平面上的一个个点，明白了？这样一来上面的&#8220;有序集&#8221;也好理解了，偏<br />
序关系a&gt;b&gt;c&gt;d&gt;...（不知道&#8220;偏序关系&#8221;就把它们看作是数组x[1]=a, x[2]=b, x[3]=c, x[4]=d ...好了）等效于无序集{(1, a), (2, b), (3, c), (4, d), ...}，于是乎，所有的<br />
集合都等效于无序集！所以高中只教了我们一种集合，呵呵&#8230;&#8230; <br />
JCF的全家福</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;&nbsp;&nbsp; 好啦好啦，这些我们都知道，又不是在上数学课，说了这么多废话，怎么还没扯到正题上来？JCF的影子我还没看见呢！列位看官别急，这就给您道来。其实上面的概<br />
念对理解JCF非常重要。<br />
&nbsp;&nbsp;&nbsp; JCF是个颇有点规模的家族，看看它的类层次关系图就知道了，下面这张图（图1）摘自著名的Thinking in Java：<br />
</span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑"><img title="JCF 家族" border="0" alt="o_collection.gif" src="http://www.blogjava.net/images/blogjava_net/jungleford/924/o_collection.gif" width="480" height="435" twffan="done" /><br />
&nbsp;&nbsp;&nbsp;图1 JCF层次结构</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;&nbsp;&nbsp; 哇，这么多接口和类，真有点让人无从下手的感觉。其实我们真正需要记住的只是这么一个超超easy的结构（图2）：</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑"><img title="简化的 JCF 骨架" border="0" alt="o_collection1.gif" src="http://www.blogjava.net/images/blogjava_net/jungleford/924/o_collection1.gif" width="289" height="145" twffan="done" /><br />
<span style="font-family: Courier">&nbsp;图2</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;&nbsp;&nbsp; 这张图看起来舒服多了吧？但它又能说明什么问题呢？它怎么就能够把握整个JCF呢？我们把Collection接口置于最顶上，意思是想说：Collection其实是整个JCF家<br />
族中的&#8220;祖宗&#8221;，几乎所有的JCF成员都源自该接口，或者和它有密切的关系，Collection提供关于集合的一些通用操作的接口，包括插入（add()方法）、删除<br />
（remove()方法）、判断一个元素是不是其成员（contains()方法）、遍历（iterator()方法）等等。注意了，前面的&#8220;废话&#8221;在这里将得到体现：Set接口体现的是<br />
&#8220;无序集&#8221;的概念，它是不允许有重复元素出现的；List接口代表&#8220;有序集&#8221;；而Map接口则是&#8220;映射&#8221;（在早期的Java版本中并不叫Map，我们在后面会看到），<br />
其实Map.Entry接口就是代表一个&#8220;元素对&#8221;我们可以通过Map的entrySet()方法得到这样一个由&#8220;元素对&#8221;组成的Set对象。我们注意到Set和List都是从&#8220;祖宗&#8221;<br />
Collection派生的，而Map不是，毕竟对一对元素的操作与对单个元素的操作还是有区别的，但是如果你仔细对照一下Collection和Map的源代码，以及它们的直接后代<br />
AbstractCollection和AbstractMap的源代码，你将会发现很多相似的地方，所以我们仍然可以把Map看成是和Collection有着血缘关系的接口，而和Set，List一起处于<br />
并列的位置。<br />
&nbsp;&nbsp;&nbsp; 有了&#8220;无序集&#8221;，&#8220;有序集&#8221;和&#8220;映射&#8221;，我们就可以定义各种各样的抽象数据结构了，譬如图1所示的向量，链表，堆栈，哈希表，平衡二叉树等。但我们需要记住<br />
的，仅仅是图2，置于其它的成员，在用到的时候查一下API手册不就行了？不过一般初学者还是比较容易用到一些类，像Vector、ArrayList、HashMap，我在这里列了<br />
一张表，显示了常见的JCF成员及其关系： </span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;&nbsp; <img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/jeromekwok/jcf.jpg" width="930" height="333" /></span></span></span></span></span></span></span></span></pre>
</span></span></span></span></span>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;&nbsp;&nbsp; 可能有的概念您还不是太了解，譬如什么叫&#8220;历史集合&#8221;，Hashtable、HashMap、TreeMap三者之间有什么区别和联系，怎样实现对一个特定集合的快速遍历、元<br />
素查找或者排序，没关系，我们在下面将逐一进行研究。 </span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">细节考虑：目标与效率</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;&nbsp;&nbsp; 有了JCF的层次还不够，重要的是对集合所容纳的对象的具体操作，以前我们学数据结构的时候可能老师总会让你计算一个算法的时间复杂度，可能你会对这个O(f(n))<br />
很不耐烦，但事实上算法效率是一个重要的因素。</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">1. 侧重点：遍历 vs. 查找<br />
&nbsp;&nbsp;&nbsp; 对集合的有两个主要的应用：我需要知道集合有哪些元素；根据条件找到一个特定的元素。在算法上通常称为&#8220;遍历&#8221;和&#8220;查找&#8221;。不要以为我们生活中不常用哦！譬<br />
如CCTV的&#8220;幸运52&#8221;里面，李咏让参赛者报出一款PDA的准确价位，他会怎么做？&#8220;2000&#8221;&#8220;高了&#8221;&#8220;1000&#8221;&#8220;低了&#8221;&#8220;1500&#8221;&#8220;低了&#8221;&#8230;&#8230;直到答对为止。可能有<br />
很多人都会选择这个策略，无论他是不是计算机专业出身的，也不知道他是不是了解&#8220;数据结构&#8221;和&#8220;折半查找&#8221;，更不用说他是不是知道还有比在无初始代价下O(log n)<br />
的时间复杂度更快的算法了，但我们经常会自然而然地用这样的方法，这和一个人的行业无关，除非这个人的rp超强，呵呵&#8230;&#8230;<br />
&nbsp;&nbsp;&nbsp; 又讲了一堆题外话了，遍历和修改似乎是一对矛盾，一个可以高效率插入删除元素的数据结构通常遍历的性能并不是最优。于是JCF在这里根据用户的目标实现了两种定<br />
制的数据结构：哈希表（包括HashSet和HashMap）和平衡二叉树（包括TreeSet和TreeMap）。由于可排序性是一种独特的要求，所以引入了SortedSet和SortedMap，<br />
它们分别是AbstractSet和AbstractMap的子接口，而TreeSet和TreeMap又分别是他们的一种实现。熟悉数据结构的人可能比较了解，哈希表在进行插入、删除、查找这<br />
样的操作是很快的，其时间复杂度是常数级O(1)；平衡二叉树虽然插入、删除操作比较麻烦（需要O(log n)的代价），但进行遍历和排序却很快。选择完全在于用户的侧重<br />
点，但由于类型转换的方便性，通常我们用哈希表构造一个集合以后，再把它转换成相应的树集进行遍历，以获得较好的效果。 </span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><br />
<span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">Set set1 = new HashSet();<br />
set1.add(elem1);// 通过插入元素构造集合<br />
set1.add(elem2);<br />
set1.add(elem3);<br />
Set set2 = new TreeSet(set);<br />
Iterator all = set2.iterator();<br />
while (all.hasNext())<br />
{// 遍历集合<br />
all.next();<br />
...<br />
} </span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">2. 历史实现 vs. 新实现<br />
&nbsp;&nbsp;&nbsp; 历史实现（Legacy Implementations）是JCF的一个术语，准确的意义不是很清楚，但大致可以认为在Java 2（JDK 1.2）出现以前的老版本中JCF的一个雏形框架。<br />
在Java 2以后，JCF才开始完善健壮起来，新实现中出现了一些新的类用于替代老版本中的成员，但由于种种原因，老版本中很多类都代表了传统数据结构的精髓部分，<br />
以及一些安全原因，所以仍然被我们使用着。</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">Enumeration vs. Iterator<br />
&nbsp;&nbsp;&nbsp; Enumeration是一个传统的集合遍历工具，在新的JCF中使用的是Iterator，Iterator同样具有遍历功能，还包含一个remove()方法来删除当前得到的元素。</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">Dictionary vs. Map<br />
&nbsp;&nbsp;&nbsp; Dictionary是一个现在已经被标记为deprecated的类，实现了老版本中的映射功能，现在已经完全被Map取代。它们的区别是：Dictionary中key和value不能为null，<br />
但Map却允许空的关键字和值，这一点直接影响到它们的后代：Hashtable和HashMap。</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">Vector vs. ArrayList<br />
&nbsp;&nbsp;&nbsp; Vector和ArrayList是数组在JCF中的体现，还记得前面讲过的数组的缺点么？Vector和ArrayList就是一种可以动态增长的数组。Vector是历史实现，它和ArrayList<br />
的主要区别在于，Vector是同步集合（或者说是线程安全的），但ArrayList并不是同步的，由于同步需要花一定的代价，所以ArrayList看起来要比Vector的存取访问效<br />
率更高。关于同步我们下面还将要谈到。</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">Hashtable vs. HashMap<br />
&nbsp;&nbsp;&nbsp; Hashtable是Dictionary的子类，属于历史实现，而HashMap是Map的子类，是新实现。它们的区别除了上面所说的key和value是否可以为空之外，也有同步的差别<br />
，Hashtable是同步的，但HashMap不是。HashMap的一个经典的例子就是JSP的内置对象session。不过不要因为Hashtable是&#8220;老前辈&#8221;而瞧不起它哦，它的一个著<br />
名的子类Properties我们可是经常会用到的。 <br />
3. 同步 vs. 不同步<br />
&nbsp;&nbsp;&nbsp; 从上面的描述中我们似乎可以得出这么一个印象：历史实现好像都是同步的，但新实现中却没有。需要同步操作的理由是，可能存在多个线程对同一个集合进行操作<br />
的情况：譬如一个线程正在对某集合进行遍历，但与此同时，另一个线程又在对该集合进行插入或删除，那么第一个线程的遍历结果将是不可预测的，对于同步集合，<br />
它将会抛出一个ConcurrentModificationException异常，JCF把这种机制成为&#8220;fail-fast&#8221;。我们对比一下Vector和ArrayList的源代码就可以发现Vector的很多方法都<br />
是有synchronized关键字修饰的，但ArrayList没有。 <br />
4. 容易遗忘的工具：Collections和Arrays <br />
&nbsp;&nbsp;&nbsp; 在图1中右下角落里有两个类叫做Collections（注意，不是Collection！）和Arrays，这是JCF里面功能强大的工具，但初学者往往会忽视。按JCF文档的说法，这两个<br />
类提供了封装器实现（Wrapper Implementations）、数据结构算法和数组相关的应用。<br />
&nbsp;&nbsp;&nbsp; 想必大家不会忘记上面谈到的&#8220;折半查找&#8221;、&#8220;排序&#8221;等经典算法吧，Collections类提供了丰富的静态方法帮助我们轻松完成这些在数据结构课上烦人的工作：</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">binarySearch：折半查找。<br />
sort：排序，这里是一种类似于快速排序的方法，效率仍然是O(n * log n)，但却是一种稳定的排序方法。<br />
reverse：将线性表进行逆序操作，这个可是从前数据结构的经典考题哦！<br />
rotate：以某个元素为轴心将线性表&#8220;旋转&#8221;——哇，这个功能太酷了！<br />
swap：交换一个线性表中两个元素的位置。<br />
&#8230;&#8230;</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;&nbsp;&nbsp; Collections还有一个重要功能就是&#8220;封装器&#8221;（Wrapper），它提供了一些方法可以把一个集合转换成一个特殊的集合：</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">unmodifiableXXX：转换成只读集合，这里XXX代表六种基本集合接口：Collection、List、Map、Set、SortedMap和SortedSet。如果你对只读集合进行插入删除操作<br />
，将会抛出UnsupportedOperationException异常。<br />
synchronizedXXX：转换成同步集合。<br />
singleton：创建一个仅有一个元素的集合，这里singleton生成的是单元素Set，singletonList和singletonMap分别生成单元素的List和Map。<br />
空集：由Collections的静态属性EMPTY_SET、EMPTY_LIST和EMPTY_MAP表示。</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">&nbsp;&nbsp;&nbsp; 此外，我们知道把集合转换成对象数组可以用Collection的toArray()方法，我们也可以方便地把一个对象数组转换成一个线性表（可不要告诉我你是一个一个地add哦）<br />
：Arrays.asList()。 <br />
5. 泛型<br />
&nbsp;&nbsp;&nbsp; 目前我们了解的JCF的一个重要特征是：所有加入到集合当中的对象都将在表面上失去它们自己的特性，而看上去仅仅只是一个Object对象而已，除非你把它强制类型<br />
转换成它们原来的对象。这一点很自然，集合嘛，对象的容器，它容纳的是各种各样的对象，而不仅仅是某种特定类型的对象。J2SE 5.0出现以后，JCF开始引入泛型的特<br />
性，譬如我们经常碰到这样的应用，就是把集合转换成特定的数组，虽然Collection有toArray()的方法，但可惜的是，这个数组的所有元素都是Object类型的，我们通常<br />
<br />
的做法是用一个for循环把数组的每个元素都进行强制类型转换，虽然可行，但看上去很笨拙，如果有了泛型，我们就可以预先指定要得到的类型，然后一次toArray就可以<br />
得到我们期望的数组，里面的元素全部都是指定类型了。惭愧的是，我对5.0还不是太了解，具体可以参考J2SE 5.0的JCF文档。 </span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Courier"><span style="font-family: Courier"><span style="font-family: Impact"><span style="font-family: Courier"><span style="font-family: 微软雅黑"><span style="font-family: Lucida Console"><span style="font-family: Comic Sans MS"><span style="font-family: 隶书"><span style="font-family: 微软雅黑"><span style="font-family: Tahoma"><span style="font-family: Courier"><span style="font-family: Comic Sans MS"><span style="font-family: 微软雅黑">本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/jenhy/archive/2008/04/28/2338986.aspx</span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></dt></dl>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/339888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-12-06 11:14 <a href="http://www.blogjava.net/JeromeKwok/articles/339888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java:重写equals()和hashCode()</title><link>http://www.blogjava.net/JeromeKwok/articles/317706.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 08 Apr 2010 04:20:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/317706.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;只有注册用户登录后才能阅读该文。<a href='http://www.blogjava.net/JeromeKwok/articles/317706.html'>阅读全文</a><img src ="http://www.blogjava.net/JeromeKwok/aggbug/317706.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-04-08 12:20 <a href="http://www.blogjava.net/JeromeKwok/articles/317706.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java加密和数字签名</title><link>http://www.blogjava.net/JeromeKwok/articles/311983.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:45:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311983.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311983.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311983.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311983.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311983.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; 本文主要谈一下密码学中的加密和数字签名，以及其在java中如何进行使用。对密码学有兴趣的伙伴，推荐看 Bruce Schneier的著作：Applied Crypotography。在jdk1.5的发行版本中安全性方面有了很大的改进，也提供了对RSA算法的直接支持，现在我们从实例入手解决问题（本文仅是作为简单介绍）： 　　一、密码学上常用的概念　　　1）消息摘要：...&nbsp;&nbsp;<a href='http://www.blogjava.net/JeromeKwok/articles/311983.html'>阅读全文</a><img src ="http://www.blogjava.net/JeromeKwok/aggbug/311983.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:45 <a href="http://www.blogjava.net/JeromeKwok/articles/311983.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>四个有用的过虑器 Filter</title><link>http://www.blogjava.net/JeromeKwok/articles/311982.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:44:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311982.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311982.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311982.html</trackback:ping><description><![CDATA[<p><a><span style="font-family: Courier; font-size: 10pt">&nbsp; </p>
<p style="font-family: "></a><a style="font-family: ">一、使浏览器不缓存页面的过滤器 </a><a></p>
<p style="font-family: ">import javax.servlet.*;<br style="font-family: " />
import javax.servlet.http.HttpServletResponse;<br style="font-family: " />
import java.io.IOException;</p>
<p style="font-family: ">/**<br style="font-family: " />
&nbsp;* 用于的使 Browser 不缓存页面的过滤器<br style="font-family: " />
&nbsp;*/<br style="font-family: " />
public class ForceNoCacheFilter&nbsp;implements Filter {</p>
<p style="font-family: ">&nbsp;public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;((HttpServletResponse) response).setHeader("Cache-Control","no-cache");<br style="font-family: " />
&nbsp;&nbsp;((HttpServletResponse) response).setHeader("Pragma","no-cache");<br style="font-family: " />
&nbsp;&nbsp;((HttpServletResponse) response).setDateHeader ("Expires", -1);<br style="font-family: " />
&nbsp;&nbsp;filterChain.doFilter(request, response);<br style="font-family: " />
&nbsp;}</p>
<p style="font-family: ">&nbsp;public void destroy()<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;}</p>
<p style="font-family: ">&nbsp;&nbsp;&nbsp; public void init(FilterConfig filterConfig) throws ServletException<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;}<br style="font-family: " />
}</p>
<p style="font-family: ">二、检测用户是否登陆的过滤器</p>
<p style="font-family: ">import javax.servlet.*;<br style="font-family: " />
import javax.servlet.http.HttpServletRequest;<br style="font-family: " />
import javax.servlet.http.HttpServletResponse;<br style="font-family: " />
import javax.servlet.http.HttpSession;<br style="font-family: " />
import java.util.List;<br style="font-family: " />
import java.util.ArrayList;<br style="font-family: " />
import java.util.StringTokenizer;<br style="font-family: " />
import java.io.IOException;</p>
<p style="font-family: ">/**<br style="font-family: " />
&nbsp;* 用于检测用户是否登陆的过滤器，如果未登录，则重定向到指的登录页面&lt;p&gt;<br style="font-family: " />
&nbsp;* 配置参数&lt;p&gt;<br style="font-family: " />
&nbsp;* checkSessionKey 需检查的在 Session 中保存的关键字&lt;br/&gt;<br style="font-family: " />
&nbsp;* redirectURL 如果用户未登录，则重定向到指定的页面，URL不包括 ContextPath&lt;br/&gt;<br style="font-family: " />
&nbsp;* notCheckURLList 不做检查的URL列表，以分号分开，并且 URL 中不包括 ContextPath&lt;br/&gt;<br style="font-family: " />
&nbsp;*/<br style="font-family: " />
public class CheckLoginFilter<br style="font-family: " />
&nbsp;implements Filter<br style="font-family: " />
{<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;protected FilterConfig filterConfig = null;<br style="font-family: " />
&nbsp;&nbsp;&nbsp; private String redirectURL = null;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;private List notCheckURLList = new ArrayList();<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;private String sessionKey = null;</p>
<p style="font-family: ">&nbsp;public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;HttpServletRequest request = (HttpServletRequest) servletRequest;<br style="font-family: " />
&nbsp;&nbsp;HttpServletResponse response = (HttpServletResponse) servletResponse;</p>
<p style="font-family: ">&nbsp;&nbsp; HttpSession session = request.getSession();<br style="font-family: " />
&nbsp;&nbsp;if(sessionKey == null)<br style="font-family: " />
&nbsp;&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;&nbsp;filterChain.doFilter(request, response);<br style="font-family: " />
&nbsp;&nbsp;&nbsp;return;<br style="font-family: " />
&nbsp;&nbsp;}<br style="font-family: " />
&nbsp;&nbsp;if((!checkRequestURIIntNotFilterList(request)) &amp;&amp; session.getAttribute(sessionKey) == null)<br style="font-family: " />
&nbsp;&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;&nbsp;response.sendRedirect(request.getContextPath() + redirectURL);<br style="font-family: " />
&nbsp;&nbsp;&nbsp;return;<br style="font-family: " />
&nbsp;&nbsp;}<br style="font-family: " />
&nbsp;&nbsp;filterChain.doFilter(servletRequest, servletResponse);<br style="font-family: " />
&nbsp;}</p>
<p style="font-family: ">&nbsp;public void destroy()<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;notCheckURLList.clear();<br style="font-family: " />
&nbsp;}</p>
<p style="font-family: ">&nbsp;private boolean checkRequestURIIntNotFilterList(HttpServletRequest request)<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;String uri = request.getServletPath() + (request.getPathInfo() == null ? "" : request.getPathInfo());<br style="font-family: " />
&nbsp;&nbsp;return notCheckURLList.contains(uri);<br style="font-family: " />
&nbsp;}</p>
<p style="font-family: ">&nbsp;public void init(FilterConfig filterConfig) throws ServletException<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;this.filterConfig = filterConfig;<br style="font-family: " />
&nbsp;&nbsp;redirectURL = filterConfig.getInitParameter("redirectURL");<br style="font-family: " />
&nbsp; sessionKey = filterConfig.getInitParameter("checkSessionKey");</p>
<p style="font-family: ">&nbsp;&nbsp;String notCheckURLListStr = filterConfig.getInitParameter("notCheckURLList");</p>
<p style="font-family: ">&nbsp;&nbsp;if(notCheckURLListStr != null)<br style="font-family: " />
&nbsp;&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;&nbsp;StringTokenizer st = new StringTokenizer(notCheckURLListStr, ";");<br style="font-family: " />
&nbsp;&nbsp;&nbsp;notCheckURLList.clear();<br style="font-family: " />
&nbsp;&nbsp;&nbsp;while(st.hasMoreTokens())<br style="font-family: " />
&nbsp;&nbsp;&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;notCheckURLList.add(st.nextToken());<br style="font-family: " />
&nbsp;&nbsp;&nbsp;}<br style="font-family: " />
&nbsp;&nbsp;}<br style="font-family: " />
&nbsp;}<br style="font-family: " />
}</p>
<p style="font-family: ">三、字符编码的过滤器</p>
<p style="font-family: ">import javax.servlet.*;<br style="font-family: " />
import java.io.IOException;</p>
<p style="font-family: ">/**<br style="font-family: " />
&nbsp;* 用于设置 HTTP 请求字符编码的过滤器，通过过滤器参数encoding指明使用何种字符编码,用于处理Html Form请求参数的中文问题<br style="font-family: " />
&nbsp;*/<br style="font-family: " />
public class CharacterEncodingFilter<br style="font-family: " />
&nbsp;implements Filter<br style="font-family: " />
{<br style="font-family: " />
&nbsp;protected FilterConfig filterConfig = null;<br style="font-family: " />
&nbsp;protected String encoding = "";</p>
<p style="font-family: ">&nbsp;public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(encoding != null)<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servletRequest.setCharacterEncoding(encoding);<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filterChain.doFilter(servletRequest, servletResponse);<br style="font-family: " />
&nbsp;}</p>
<p style="font-family: ">&nbsp;public void destroy()<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;filterConfig = null;<br style="font-family: " />
&nbsp;&nbsp;encoding = null;<br style="font-family: " />
&nbsp;}</p>
<p style="font-family: ">&nbsp;&nbsp;&nbsp; public void init(FilterConfig filterConfig) throws ServletException<br style="font-family: " />
&nbsp;{<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.filterConfig = filterConfig;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.encoding = filterConfig.getInitParameter("encoding");</p>
<p style="font-family: ">&nbsp;}<br style="font-family: " />
}</p>
<p style="font-family: ">四、资源保护过滤器</p>
<pre style="font-family: ">package catalog.view.util;<br style="font-family: " />
<br style="font-family: " />
import javax.servlet.Filter;<br style="font-family: " />
import javax.servlet.FilterConfig;<br style="font-family: " />
import javax.servlet.ServletRequest;<br style="font-family: " />
import javax.servlet.ServletResponse;<br style="font-family: " />
import javax.servlet.FilterChain;<br style="font-family: " />
import javax.servlet.ServletException;<br style="font-family: " />
import javax.servlet.http.HttpServletRequest;<br style="font-family: " />
import java.io.IOException;<br style="font-family: " />
import java.util.Iterator;<br style="font-family: " />
import java.util.Set;<br style="font-family: " />
import java.util.HashSet;<br style="font-family: " />
//<br style="font-family: " />
import org.apache.commons.logging.Log;<br style="font-family: " />
import org.apache.commons.logging.LogFactory;<br style="font-family: " />
<br style="font-family: " />
/**<br style="font-family: " />
* This Filter class handle the security of the application.<br style="font-family: " />
*
<p style="font-family: "><br style="font-family: " />
* It should be configured inside the web.xml.<br style="font-family: " />
* <br style="font-family: " />
* @author </a><a style="font-family: " href="mailto:derek_shen@hotmail.com" mce_href="mailto:derek_shen@hotmail.com">Derek Y. Shen</a><a><br style="font-family: " />
*/<br style="font-family: " />
public class SecurityFilter implements Filter {<br style="font-family: " />
//the login page uri<br style="font-family: " />
private static final String LOGIN_PAGE_URI = "login.jsf";<br style="font-family: " />
<br style="font-family: " />
//the logger object<br style="font-family: " />
private Log logger = LogFactory.getLog(this.getClass());<br style="font-family: " />
<br style="font-family: " />
//a set of restricted resources<br style="font-family: " />
private Set restrictedResources;<br style="font-family: " />
<br style="font-family: " />
/**<br style="font-family: " />
* Initializes the Filter.<br style="font-family: " />
*/<br style="font-family: " />
public void init(FilterConfig filterConfig) throws ServletException {<br style="font-family: " />
this.restrictedResources = new HashSet();<br style="font-family: " />
this.restrictedResources.add("/createProduct.jsf");<br style="font-family: " />
this.restrictedResources.add("/editProduct.jsf");<br style="font-family: " />
this.restrictedResources.add("/productList.jsf");<br style="font-family: " />
}<br style="font-family: " />
<br style="font-family: " />
/**<br style="font-family: " />
* Standard doFilter object.<br style="font-family: " />
*/<br style="font-family: " />
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)<br style="font-family: " />
throws IOException, ServletException {<br style="font-family: " />
this.logger.debug("doFilter");<br style="font-family: " />
<br style="font-family: " />
String contextPath = ((HttpServletRequest)req).getContextPath();<br style="font-family: " />
String requestUri = ((HttpServletRequest)req).getRequestURI();<br style="font-family: " />
<br style="font-family: " />
this.logger.debug("contextPath = " + contextPath);<br style="font-family: " />
this.logger.debug("requestUri = " + requestUri);<br style="font-family: " />
<br style="font-family: " />
if (this.contains(requestUri, contextPath) &amp;&amp; !this.authorize((HttpServletRequest)req)) {<br style="font-family: " />
this.logger.debug("authorization failed");<br style="font-family: " />
((HttpServletRequest)req).getRequestDispatcher(LOGIN_PAGE_URI).forward(req, res);<br style="font-family: " />
}<br style="font-family: " />
else {<br style="font-family: " />
this.logger.debug("authorization succeeded");<br style="font-family: " />
chain.doFilter(req, res);<br style="font-family: " />
}<br style="font-family: " />
}<br style="font-family: " />
<br style="font-family: " />
public void destroy() {} <br style="font-family: " />
<br style="font-family: " />
private boolean contains(String value, String contextPath) {<br style="font-family: " />
Iterator ite = this.restrictedResources.iterator();<br style="font-family: " />
<br style="font-family: " />
while (ite.hasNext()) {<br style="font-family: " />
String restrictedResource = (String)ite.next();<br style="font-family: " />
<br style="font-family: " />
if ((contextPath + restrictedResource).equalsIgnoreCase(value)) {<br style="font-family: " />
return true;<br style="font-family: " />
}<br style="font-family: " />
}<br style="font-family: " />
<br style="font-family: " />
return false;<br style="font-family: " />
}<br style="font-family: " />
<br style="font-family: " />
private boolean authorize(HttpServletRequest req) {<br style="font-family: " />
<br style="font-family: " />
//处理用户登录<br style="font-family: " />
/*	UserBean user = (UserBean)req.getSession().getAttribute(BeanNames.USER_BEAN);<br style="font-family: " />
<br style="font-family: " />
if (user != null &amp;&amp; user.getLoggedIn()) {<br style="font-family: " />
//user logged in<br style="font-family: " />
return true;<br style="font-family: " />
}<br style="font-family: " />
else {<br style="font-family: " />
return false;<br style="font-family: " />
}*/<br style="font-family: " />
}<br style="font-family: " />
}</p>
</pre>
<p style="font-family: ">&nbsp;</p>
</span></a>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:44 <a href="http://www.blogjava.net/JeromeKwok/articles/311982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式 </title><link>http://www.blogjava.net/JeromeKwok/articles/311981.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:41:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311981.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311981.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311981.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311981.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311981.html</trackback:ping><description><![CDATA[<p><span style="font-family: Courier"><span style="font-size: 10pt">正则表达式 <br />
　　是由普通字符（例如字符 a 到 z）以及特殊字符（称为元字符）组成的文字模式。正则表达式作为一个模板，将某个字符模式与所搜索的字符串进行匹配。 <br />
　　可以通过在一对分隔符之间放入表达式模式的各种组件来构造一个正则表达式，即/expression/ </span></span></p>
<p><br />
<span style="font-family: Courier"><span style="font-size: 10pt">普通字符 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">　　由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符，所有数字，所有标点符号以及一些符号。 </span></span></p>
<p><br />
<span style="font-family: Courier"><span style="font-size: 10pt">非打印字符 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">字符 含义 <br />
\cx 匹配由x指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。 <br />
\f 匹配一个换页符。等价于 \x0c 和 \cL。 <br />
\n 匹配一个换行符。等价于 \x0a 和 \cJ。 <br />
\r 匹配一个回车符。等价于 \x0d 和 \cM。 <br />
\s 匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 <br />
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 <br />
\t 匹配一个制表符。等价于 \x09 和 \cI。 <br />
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">&nbsp;</span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">特殊字符 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">　　所谓特殊字符，就是一些有特殊含义的字符，如上面说的"*.txt"中的*，简单的说就是表示任何字符串的意思。如果要查找文件名中有＊的文件，则需要对＊进行转义，即在其前加一个\。ls \*.txt。正则表达式有以下特殊字符。 <br />
特别字符 说明 <br />
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性，则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身，请使用 \$。 <br />
( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符，请使用 \( 和 \)。 <br />
* 匹配前面的子表达式零次或多次。要匹配 * 字符，请使用 \*。 <br />
+ 匹配前面的子表达式一次或多次。要匹配 + 字符，请使用 \+。 <br />
. 匹配除换行符 \n之外的任何单字符。要匹配 .，请使用 \。 <br />
[ 标记一个中括号表达式的开始。要匹配 [，请使用 \[。 <br />
? 匹配前面的子表达式零次或一次，或指明一个非贪婪限定符。要匹配 ? 字符，请使用 \?。 <br />
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如， 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\"，而 '\(' 则匹配 "("。 <br />
^ 匹配输入字符串的开始位置，除非在方括号表达式中使用，此时它表示不接受该字符集合。要匹配 ^ 字符本身，请使用 \^。 <br />
{ 标记限定符表达式的开始。要匹配 {，请使用 \{。 <br />
| 指明两项之间的一个选择。要匹配 |，请使用 \|。 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">&nbsp;</span></span></p>
<p><br />
<span style="font-family: Courier"><span style="font-size: 10pt">　　构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">&nbsp;</span></span></p>
<p><br />
<span style="font-family: Courier"><span style="font-size: 10pt">限定符 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">　　限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。 <br />
*、+和?限定符都是贪婪的，因为它们会尽可能多的匹配文字，只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。 <br />
　　正则表达式的限定符有： <br />
字符 描述 <br />
* 匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 <br />
+ 匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。 <br />
? 匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 <br />
{n} n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。 <br />
{n,} n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 <br />
{n,m} m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">&nbsp;</span></span></p>
<p><br />
<span style="font-family: Courier"><span style="font-size: 10pt">定位符 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">　　用来描述字符串或单词的边界，^和$分别指字符串的开始与结束，\b描述单词的前或后边界，\B表示非单词边界。不能对定位符使用限定符。 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">&nbsp;</span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">选择 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">　　用圆括号将所有选择项括起来，相邻的选择项之间用|分隔。但用圆括号会有一个副作用，是相关的匹配会被缓存，此时可用?:放在第一个选项前来消除这种副作用。 <br />
　　其中?:是非捕获元之一，还有两个非捕获元是?=和?!，这两个还有更多的含义，前者为正向预查，在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串，后者为负向预查，在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">&nbsp;</span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">后向引用 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">　　对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中，所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从 1 开始，连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 '\n' 访问，其中 n 为一个标识特定缓冲区的一位或两位十进制数。 <br />
　　可以使用非捕获元字符 '?:', '?=', or '?!' 来忽略对相关匹配的保存。 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">&nbsp;</span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">各种操作符的运算优先级 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">　　相同优先级的从左到右进行运算，不同优先级的运算先高后低。各种操作符的优先级从高到低如下： <br />
操作符 描述 <br />
\ 转义符 <br />
(), (?:), (?=), [] 圆括号和方括号 <br />
*, +, ?, {n}, {n,}, {n,m} 限定符 <br />
^, $, \anymetacharacter 位置和顺序 <br />
| &#8220;或&#8221;操作 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">&nbsp;</span></span></p>
<p><br />
<span style="font-family: Courier"><span style="font-size: 10pt">全部符号解释 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">字符 描述 <br />
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如，'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。 <br />
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性，^ 也匹配 '\n' 或 '\r' 之后的位置。 <br />
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性，$ 也匹配 '\n' 或 '\r' 之前的位置。 <br />
* 匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 <br />
+ 匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。 <br />
? 匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 <br />
{n} n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。 <br />
{n,} n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 <br />
{n,m} m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 <br />
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 "oooo"，'o+?' 将匹配单个 "o"，而 'o+' 将匹配所有 'o'。 <br />
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符，请使用象 '[.\n]' 的模式。 <br />
(pattern) 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 SubMatches 集合，在JScript 中则使用 $0&#8230;$9 属性。要匹配圆括号字符，请使用 '\(' 或 '\)'。 <br />
(?:pattern) 匹配 pattern 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如， 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。 <br />
(?=pattern) 正向预查，在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如，'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ，但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。 <br />
(?!pattern) 负向预查，在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows"，但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始 <br />
x|y 匹配 x 或 y。例如，'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。 <br />
[xyz] 字符集合。匹配所包含的任意一个字符。例如， '[abc]' 可以匹配 "plain" 中的 'a'。 <br />
[^xyz] 负值字符集合。匹配未包含的任意字符。例如， '[^abc]' 可以匹配 "plain" 中的'p'。 <br />
[a-z] 字符范围。匹配指定范围内的任意字符。例如，'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。 <br />
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如，'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。 <br />
\b 匹配一个单词边界，也就是指单词和空格间的位置。例如， 'er\b' 可以匹配"never" 中的 'er'，但不能匹配 "verb" 中的 'er'。 <br />
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er'，但不能匹配 "never" 中的 'er'。 <br />
\cx 匹配由 x 指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。 <br />
\d 匹配一个数字字符。等价于 [0-9]。 <br />
\D 匹配一个非数字字符。等价于 [^0-9]。 <br />
\f 匹配一个换页符。等价于 \x0c 和 \cL。 <br />
\n 匹配一个换行符。等价于 \x0a 和 \cJ。 <br />
\r 匹配一个回车符。等价于 \x0d 和 \cM。 <br />
\s 匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 <br />
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 <br />
\t 匹配一个制表符。等价于 \x09 和 \cI。 <br />
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。 <br />
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 <br />
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 <br />
\xn 匹配 n，其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如，'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' &amp; "1"。正则表达式中可以使用 ASCII 编码。. <br />
\num 匹配 num，其中 num 是一个正整数。对所获取的匹配的引用。例如，'(.)\1' 匹配两个连续的相同字符。 <br />
\n 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式，则 n 为向后引用。否则，如果 n 为八进制数字 (0-7)，则 n 为一个八进制转义值。 <br />
\nm 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式，则 nm 为向后引用。如果 \nm 之前至少有 n 个获取，则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足，若 n 和 m 均为八进制数字 (0-7)，则 \nm 将匹配八进制转义值 nm。 <br />
\nml 如果 n 为八进制数字 (0-3)，且 m 和 l 均为八进制数字 (0-7)，则匹配八进制转义值 nml。 <br />
\un 匹配 n，其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (?)。 </span></span></p>
<p><br />
<span style="font-family: Courier"><span style="font-size: 10pt">VBScript内的使用方法： </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">function gfCheck(obj) </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">dim strCheck '待检字符串 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">dim objRE '正则式对象 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">dim strRtn '正则式判断结果 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">strCheck = obj.value </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">set objRE = New RegExp </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">objRE.Pattern = "^[A-Za-z0-9]{13}$" '13位的英文字符和数字串 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">gfCheck = objRE.Test(strCheck) '符合正则式则返回true，反之则返回false </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">set objRE = nothing </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">end function </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">常用的正则式 </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">1、非负整数：&#8221;^\d+$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">2、正整数：&#8221;^[0-9]*[1-9][0-9]*$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">3、非正整数：&#8221;^((-\d+)|(0+))$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">4、负整数：&#8221;^-[0-9]*[1-9][0-9]*$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">5、整数：&#8221;^-?\d+$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">6、非负浮点数：&#8221;^\d+(\.\d+)?$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">7、正浮点数：&#8221;^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">8、非正浮点数：&#8221;^((-\d+\.\d+)?)|(0+(\.0+)?))$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">9、负浮点数：&#8221;^(-((正浮点数正则式)))$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">10、英文字符串：&#8221;^[A-Za-z]+$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">11、英文大写串：&#8221;^[A-Z]+$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">12、英文小写串：&#8221;^[a-z]+$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">13、英文字符数字串：&#8221;^[A-Za-z0-9]+$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">14、英数字加下划线串：&#8221;^\w+$&#8221; </span></span></p>
<p><span style="font-family: Courier"><span style="font-size: 10pt">15、E-mail地址：&#8221;^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$&#8221; </span></span></p>
<pre><span style="font-family: Courier"><span style="font-size: 10pt">16、URL：&#8221;^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?___FCKpd___0rdquo;&nbsp;</span></span></pre>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311981.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:41 <a href="http://www.blogjava.net/JeromeKwok/articles/311981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java正则表达式详解</title><link>http://www.blogjava.net/JeromeKwok/articles/311980.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:38:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311980.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311980.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311980.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311980.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311980.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt">
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td size="4">一、正则表达式基础知识 </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4n.jpg" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4n.jpg" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4a.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4a.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图一：匹配所有123-12-1234形式的社会安全号码
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4b.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4b.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图二：匹配所有123-12-1234和123121234形式的社会安全号码
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4c.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4c.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图三：匹配典型的美国汽车牌照号码，如8836KV
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4d.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4d.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图四：匹配所有单词，但&#8220;X&#8221;开头的除外
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td=""  圆括号和空白符号="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4e.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4e.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图五：匹配所有Moth DD,YYYY格式的日期
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4f.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4f.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图六：匹配所有Month DD,YYYY格式的日期，定义月份值为第一个组
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4o.jpg" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4o.jpg" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4g.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4g.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图七：匹配所有123-12-1234格式的社会安全号码
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td size="4">二、Jakarta-ORO库 </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td size="4">三、应用实例 </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4h.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4h.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图八：匹配IP地址
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4i.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4i.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图九：匹配至少一个字符，直至找到&#8220;]&#8221;
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td td="">&nbsp;</td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4j.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4j.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图十：匹配IP地址和时间标记
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td size="+2" face="Arial, Serif" color="#ff0000"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_n.jpg" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_n.jpg" /> </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4k.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4k.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图十一：匹配FONT标记的所有属性
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4l.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4l.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图十二：匹配单个属性，并把它分割成名字-值对
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4m.gif" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4m.gif" />
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center">
    <tbody>
        <tr>
            <td align="center">图十三：匹配修改前的链接
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<table class="mceItemTable" width="620" align="center" height="17">
    <tbody>
        <tr>
            <td height="13"><img border="0" alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_x.jpg" mce_src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_x.jpg" /> </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
</span>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311980.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:38 <a href="http://www.blogjava.net/JeromeKwok/articles/311980.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中的Collection类 </title><link>http://www.blogjava.net/JeromeKwok/articles/311979.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:37:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311979.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311979.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311979.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311979.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311979.html</trackback:ping><description><![CDATA[<p><span style="font-family: Courier New"><span style="font-size: 10pt"><span style="font-family: Courier New">线性表，链表，哈希表是常用的数据结构，在进行Java开发时，JDK已经为我们提供了一系列相应的类来实现基本的数据结构。这些类均在java.util包中。本文试图通过简单的描述，向读者阐述各个类的作用以及如何正确使用这些类。 </span></p>
<p><span style="font-family: Courier New"><em>Collection</em><br />
├<em>List</em><br />
│├LinkedList<br />
│├ArrayList<br />
│└Vector<br />
│　└Stack<br />
└<em>Set</em><br />
<em>Map</em><br />
├Hashtable<br />
├HashMap<br />
└WeakHashMap</span></p>
<p><span style="font-family: Courier New"><strong><span style="color: #0000ff">Collection接口</span></strong><br />
　　Collection是最基本的集合接口，一个Collection代表一组Object，即Collection的元素（Elements）。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类，Java SDK提供的类都是继承自Collection的&#8220;子接口&#8221;如List和Set。<br />
　　所有实现Collection接口的类都必须提供两个标准的构造函数：无参数的构造函数用于创建一个空的Collection，有一个Collection参数的构造函数用于创建一个新的Collection，这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。<br />
　　如何遍历Collection中的每一个元素？不论Collection的实际类型如何，它都支持一个iterator()的方法，该方法返回一个迭代子，使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下：<br />
</span><span style="font-family: Courier New"><span style="color: #336666">　　　　Iterator it = collection.iterator(); // 获得一个迭代子<br />
　　　　while(it.hasNext()) {<br />
　　　　　　Object obj = it.next(); // 得到下一个元素<br />
　　　　}</span><br />
　　由Collection接口派生的两个接口是List和Set。</span></p>
<p><span style="font-family: Courier New"><span style="color: #0000ff"><strong>List接口</strong></span><br />
　　List是有序的Collection，使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引（元素在List中的位置，类似于数组下标）来访问List中的元素，这类似于Java的数组。<br />
和下面要提到的Set不同，List允许有相同的元素。<br />
　　除了具有Collection接口必备的iterator()方法外，List还提供一个listIterator()方法，返回一个ListIterator接口，和标准的Iterator接口相比，ListIterator多了一些add()之类的方法，允许添加，删除，设定元素，还能向前或向后遍历。<br />
　　实现List接口的常用类有LinkedList，ArrayList，Vector和Stack。</span></p>
<p><span style="font-family: Courier New"><span style="color: #0000ff"><strong>LinkedList类</strong></span><br />
　　LinkedList实现了List接口，允许null元素。此外LinkedList提供额外的get，remove，insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈（stack），队列（queue）或双向队列（deque）。<br />
　　注意LinkedList没有同步方法。如果多个线程同时访问一个List，则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List：<br />
<span style="color: #336666">　　　　List list = Collections.synchronizedList(new LinkedList(...));</span></span></p>
<p><span style="font-family: Courier New"><span style="color: #0000ff"><strong>ArrayList类</strong></span><br />
　　ArrayList实现了可变大小的数组。它允许所有元素，包括null。ArrayList没有同步。<br />
size，isEmpty，get，set方法运行时间为常数。但是add方法开销为分摊的常数，添加n个元素需要O(n)的时间。其他的方法运行时间为线性。<br />
　　每个ArrayList实例都有一个容量（Capacity），即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加，但是增长算法并没有定义。当需要插入大量元素时，在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。<br />
　　和LinkedList一样，ArrayList也是非同步的（unsynchronized）。</span></p>
<p><span style="font-family: Courier New"><span style="color: #0000ff"><strong>Vector类</strong></span><br />
　　Vector非常类似ArrayList，但是Vector是同步的。由Vector创建的Iterator，虽然和ArrayList创建的Iterator是同一接口，但是，因为Vector是同步的，当一个Iterator被创建而且正在被使用，另一个线程改变了Vector的状态（例如，添加或删除了一些元素），这时调用Iterator的方法时将抛出ConcurrentModificationException，因此必须捕获该异常。</span></p>
<p><span style="font-family: Courier New"><strong><span style="color: #0000ff">Stack 类</span></strong><br />
　　Stack继承自Vector，实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法，还有peek方法得到栈顶的元素，empty方法测试堆栈是否为空，search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。</span></p>
<p><span style="font-family: Courier New"><span style="color: #0000ff"><strong>Set接口</strong></span><br />
　　Set是一种不包含重复的元素的Collection，即任意的两个元素e1和e2都有e1.equals(e2)=false，Set最多有一个null元素。<br />
　　很明显，Set的构造函数有一个约束条件，传入的Collection参数不能包含重复的元素。<br />
　　请注意：必须小心操作可变对象（Mutable Object）。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。</span></p>
<p><span style="font-family: Courier New"><span style="color: #0000ff"><strong>Map接口</strong></span><br />
　　请注意，Map没有继承Collection接口，Map提供key到value的映射。一个Map中不能包含相同的key，每个key只能映射一个value。Map接口提供3种集合的视图，Map的内容可以被当作一组key集合，一组value集合，或者一组key-value映射。</span></p>
<p><span style="font-family: Courier New"><span style="color: #0000ff"><strong>Hashtable类</strong></span><br />
　　Hashtable继承Map接口，实现一个key-value映射的哈希表。任何非空（non-null）的对象都可作为key或者value。<br />
　　添加数据使用put(key, value)，取出数据使用get(key)，这两个基本操作的时间开销为常数。<br />
Hashtable通过initial capacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大，这会影响像get和put这样的操作。<br />
使用Hashtable的简单示例如下，将1，2，3放到Hashtable中，他们的key分别是&#8221;one&#8221;，&#8221;two&#8221;，&#8221;three&#8221;：<br />
</span><span style="font-family: Courier New"><span style="color: #336666">　　　　Hashtable numbers = new Hashtable();<br />
　　　　numbers.put(&#8220;one&#8221;, new Integer(1));<br />
　　　　numbers.put(&#8220;two&#8221;, new Integer(2));<br />
　　　　numbers.put(&#8220;three&#8221;, new Integer(3));</span><br />
　　要取出一个数，比如2，用相应的key：<br />
</span><span style="font-family: Courier New"><span style="color: #336666">　　　　Integer n = (Integer)numbers.get(&#8220;two&#8221;);<br />
　　　　System.out.println(&#8220;two = &#8221; + n);</span><br />
　　由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置，因此任何作为key的对象都必须实现hashCode和equals方法。hashCode和equals方法继承自根类Object，如果你用自定义的类当作key的话，要相当小心，按照散列函数的定义，如果两个对象相同，即obj1.equals(obj2)=true，则它们的hashCode必须相同，但如果两个对象不同，则它们的hashCode不一定不同，如果两个不同对象的hashCode相同，这种现象称为冲突，冲突会导致操作哈希表的时间开销增大，所以尽量定义好的hashCode()方法，能加快哈希表的操作。<br />
　　如果相同的对象有不同的hashCode，对哈希表的操作会出现意想不到的结果（期待的get方法返回null），要避免这种问题，只需要牢记一条：要同时复写equals方法和hashCode方法，而不要只写其中一个。<br />
　　Hashtable是同步的。</span></p>
<p><span style="font-family: Courier New"><strong><span style="color: #0000ff">HashMap类</span></strong><br />
　　HashMap和Hashtable类似，不同之处在于HashMap是非同步的，并且允许null，即null value和null key。，但是将HashMap视为Collection时（values()方法可返回Collection），其迭代子操作时间开销和HashMap的容量成比例。因此，如果迭代操作的性能相当重要的话，不要将HashMap的初始化容量设得过高，或者load factor过低。</span></p>
<p><span style="font-family: Courier New"><span style="color: #0000ff"><strong>WeakHashMap类</strong></span><br />
　　WeakHashMap是一种改进的HashMap，它对key实行&#8220;弱引用&#8221;，如果一个key不再被外部所引用，那么该key可以被GC回收。</span></p>
<p><span style="font-family: Courier New"><span style="color: #ff0000"><strong>总结</strong></span><br />
　　如果涉及到堆栈，队列等操作，应该考虑用List，对于需要快速插入，删除元素，应该使用LinkedList，如果需要快速随机访问元素，应该使用ArrayList。<br />
　　如果程序在单线程环境中，或者访问仅仅在一个线程中进行，考虑非同步的类，其效率较高，如果多个线程可能同时操作一个类，应该使用同步的类。<br />
　　要特别注意对哈希表的操作，作为key的对象要正确复写equals和hashCode方法。<br />
　　尽量返回接口而非实际的类型，如返回List而非ArrayList，这样如果以后需要将ArrayList换成LinkedList时，客户端代码不用改变。这就是针对抽象编程。&nbsp;</span></p>
</span></span>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:37 <a href="http://www.blogjava.net/JeromeKwok/articles/311979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实用工具类库java.util包 </title><link>http://www.blogjava.net/JeromeKwok/articles/311977.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:36:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311977.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311977.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311977.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311977.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311977.html</trackback:ping><description><![CDATA[<p><span style="font-family: Courier New"><span style="font-size: 10pt"><span style="font-family: Courier New">本章介绍Java的实用工具类库java.util包。在这个包中，Java提供了一些实用的方法和数据结构。本章介绍Java的实用工具类库java.util包。在这个包中，Java提供了一些实用的方法和数据结构。例如，Java提供日期(Data)类、日历(Calendar)类来产生和获取日期及时间，提供随机数(Random)类产生各种类型的随机数，还提供了堆栈(Stack)、向量(Vector)&nbsp;、位集合(Bitset)以及哈希表(Hashtable)等类来表示相应的数据结构。<br />
　　图8.1给出了java.util包的基本层次结构图。下面我们将具体介绍其中几个重要的类。<br />
　　　　　　　　　　　┌java.util.BitSet<br />
　　　　　　　　　　　│java.util.Calendar<br />
　　　　　　　　　　　│　　　　　　└java.util.GregorianCalendar<br />
　　　　　　　　　　　│java.util.Date<br />
　　　　　　　　　　　│java.util.Dictionary<br />
　　　　　　　　　　　│　　　　　　└java.util.Hashtable<br />
　　　　　　　　　　　│　　　　　　　　　　　　　└java.util.Properties<br />
　　　　　　　　　　　│java.util.EventObject<br />
　　　　　　　　　　　│java.util.ResourceBundle<br />
　　　　　　　┌普通类┤　　　　　　├java.util.ListResourceBundle<br />
　　　　　　　│　　　│　　　　　　└java.util.PropertyResourceBundle<br />
　　　　　　　│　　　│java.util.Local<br />
　　　　　　　│　　　│java.util.Observable<br />
　　　　　　　│　　　│java.util.Random<br />
　　　　　　　│　　　│java.util.StringTokenizer<br />
　　　　　　　│　　　│java.util.Vector<br />
　　　　　　　│　　　│　　　　　　└java.util.Stack<br />
　　Java.util┤　　　└java.util.TimeZone<br />
　　　　　　　│　　　　　　　　　　└java.util.SimpleTimeZone<br />
　　　　　　　│　　　┌java.util.Enumeration<br />
　　　　　　　├接　口┤java.util.EventListener<br />
　　　　　　　│　　　└java.util.Observer<br />
　　　　　　　│　　　┌java.util.EmptyStackException<br />
　　　　　　　└异常类┤java.util.MissingResourceException<br />
　　　　　　　　　　　│java.util.NoSuchElementException<br />
　　　　　　　　　　　└java.util.TooManyListenersException<br />
　　　　　　　图8.1&nbsp;java.util包的基本层次结构<br />
<br />
<br />
8.2&nbsp;日期类Date<br />
<br />
　　Java在日期类中封装了有关日期和时间的信息，用户可以通过调用相应的方法来获取系统时间或设置日期和时间。Date类中有很多方法在JDK1.0公布后已经过时了，在8.3中我们将介绍JDK1.0中新加的用于替代Date的功能的其它类。<br />
　　在日期类中共定义了六种构造函数。<br />
　　(1)public&nbsp;Date()<br />
　　创建的日期类对象的日期时间被设置成创建时刻相对应的日期时间。<br />
　　例&nbsp;Date&nbsp;today=new&nbsp;Date()；//today被设置成创建时刻相对应的日期时间。<br />
　　(2)public&nbsp;Date&nbsp;(long&nbsp;date)<br />
　　long&nbsp;型的参数date可以通过调用Date类中的static方法parse(String&nbsp;s)来获得。<br />
　　例&nbsp;long&nbsp;l=Date.parse("Mon&nbsp;6&nbsp;Jan&nbsp;1997&nbsp;13:3:00");<br />
　　　　Date&nbsp;day=new&nbsp;Date(l);<br />
　　//day中时间为1997年&nbsp;1月6号星期一，13:3:00。<br />
　　(3)public&nbsp;Date(String&nbsp;s)<br />
　　按字符串s产生一日期对象。s的格式与方法parse中字符串参数的模式相同。<br />
　　例&nbsp;Date&nbsp;day=new&nbsp;Date("Mon&nbsp;6&nbsp;Jan&nbsp;1997&nbsp;13:3:00");<br />
　　//day&nbsp;中时间为1997年1月6号星期一，13:3:00.<br />
　　(4)public&nbsp;Date(int&nbsp;year,int&nbsp;month,int&nbsp;date)<br />
　　(5)public&nbsp;Date(int&nbsp;year,int&nbsp;month,int&nbsp;date,int&nbsp;hrs,int&nbsp;min)<br />
　　(6)public&nbsp;Date(int&nbsp;year,int&nbsp;month,int&nbsp;date,int&nbsp;hrs,int&nbsp;min,int&nbsp;sec)<br />
　　按给定的参数创建一日期对象。<br />
　　参数说明：<br />
　　year的值为：需设定的年份-1900。例如需设定的年份是1997则year的值应为97，即1997-1900的结果。所以Date中可设定的年份最小为1900；<br />
　　month的值域为0～11，0代表1月，11表代表12月；<br />
　　date的值域在1～31之间；<br />
　　hrs的值域在0～23之间。从午夜到次日凌晨1点间hrs=0，从中午到下午1点间hrs=12；<br />
　　min和sec的值域在0～59之间。<br />
　　例&nbsp;Date&nbsp;day=new&nbsp;Date(11,3,4);<br />
　　//day中的时间为：04-Apr-11&nbsp;12:00:00&nbsp;AM<br />
另外，还可以给出不正确的参数。<br />
　　例　设定时间为1910年2月30日，它将被解释成3月2日。<br />
　　Date&nbsp;day=new&nbsp;Date(10,1,30,10,12,34);<br />
　　System.out.println("Day's&nbsp;date&nbsp;is:"+day);<br />
　　//打印结果为：Day's&nbsp;date&nbsp;is:Web&nbsp;Mar&nbsp;02&nbsp;10:13:34&nbsp;GMT+08:00&nbsp;1910<br />
　　下面我们给出一些Date类中常用方法。<br />
　　(1)public&nbsp;static&nbsp;long&nbsp;UTC(int&nbsp;year,int&nbsp;month,int&nbsp;date,int&nbsp;hrs.&nbsp;int&nbsp;min,int&nbsp;sec)<br />
　　该方法将利用给定参数计算UTC值。UTC是一种计时体制，与GMT(格林威治时间)的计时体系略有差别。UTC计时体系是基于原子时钟的，而GTMT计时体系是基于天文学观测的。计算中使用的一般为GMT计时体系。<br />
　　(2)public&nbsp;static&nbsp;long&nbsp;parse(String&nbsp;s)<br />
　　该方法将字符串s转换成一个long型的日期。在介绍构造方法Date(long&nbsp;date)时曾使用过这个方法。<br />
　　字符串s有一定的格式，一般为：<br />
　　(星期&nbsp;日&nbsp;年&nbsp;时间GMT+时区)<br />
　　若不注明时区，则为本地时区。<br />
　　(3)public&nbsp;void&nbsp;setMonth(int&nbsp;month)<br />
　　(4)public&nbsp;int&nbsp;getMonth()<br />
　　这两个方法分别为设定和获取月份值。<br />
　　获取的月份的值域为0～11，0代表1月，11代表12月。<br />
　　(5)public&nbsp;String&nbsp;toString()<br />
　　(6)public&nbsp;String&nbsp;toLocalString()<br />
　　(7)public&nbsp;String&nbsp;toGMTString()<br />
　　将给定日期对象转换成不同格式的字符串。它们对应的具体的格式可参看例子8.1。<br />
　　(8)public&nbsp;int&nbsp;getTimezoneOffset()<br />
　　该方法用于获取日期对象的时区偏移量。<br />
　　例8.1中对上面介绍的Date类中的基本方法进行了具体的应用，并打印了相应的结果。由于使用了一些过时的方法，所以编译时会有警告信息。另外，由于本例中的时间表示与平台有关，不同的JDK版本对此处理不完全相同，因此不同版本的JDK执行本例的结果可能有细微差异。<br />
　　例8.1&nbsp;DateApp.java<br />
　　import&nbsp;java.lang.System;<br />
　　import&nbsp;java.util.Date;<br />
　　public&nbsp;class&nbsp;DateApp{<br />
　　　public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;args[]){<br />
　　　　Date&nbsp;today=new&nbsp;Date();<br />
　　　　//today中的日期被设成创建时刻的日期和时间，假设创建时刻为1997年3月<br />
　　　　//23日17时51分54秒。<br />
　　　　System.out.println("Today's&nbsp;date&nbsp;is&nbsp;"+today);<br />
　　　　//返回一般的时间表示法，本例中结果为<br />
　　　　//Today's&nbsp;date&nbsp;is&nbsp;Fri&nbsp;May&nbsp;23&nbsp;17:51:54&nbsp;1997<br />
　　　　System.out.println("Today's&nbsp;date(Internet&nbsp;GMT)is:"<br />
　　　　　+today.toGMTString());<br />
　　　　//返回结果为GMT时间表示法，本例中结果为<br />
　　　　//Today's&nbsp;date(Internet&nbsp;GMT)is:&nbsp;23&nbsp;May&nbsp;1997&nbsp;09:51:54:GMT<br />
　　　　System.out.println("Today's&nbsp;date(Locale)&nbsp;is:"<br />
　　　　　+today.toLocaleString());<br />
　　　　//返回结果为本地习惯的时间表示法，结果为<br />
　　　　//Today's&nbsp;date(Locale)is:05/23/97&nbsp;17:51:54<br />
　　　　System.out.println("Today's&nbsp;year&nbsp;is:&nbsp;"+today.getYear());<br />
　　　　System.out.println("Today's&nbsp;month&nbsp;is:&nbsp;"+(today.getMonth()+1));<br />
　　　　System.out.println("Today's&nbsp;date&nbsp;is:&nbsp;"+today.getDate());<br />
　　　　//调用Date类中方法，获取年月日的值。<br />
　　　　//下面调用了不同的构造方法来创建Date类的对象。<br />
　　　　Date&nbsp;day1=new&nbsp;Date(100,1,23,10,12,34);<br />
　　　　System.out.println("Day1's&nbsp;date&nbsp;is:&nbsp;"+day1);<br />
　　　　Date&nbsp;day2=new&nbsp;Date("Sat&nbsp;12&nbsp;Aug&nbsp;1996&nbsp;13:3:00");<br />
　　　　System.out.println("Day2's&nbsp;date&nbsp;is:&nbsp;"+day2);<br />
　　　　long&nbsp;l=&nbsp;Date.parse("Sat&nbsp;5&nbsp;Aug&nbsp;1996&nbsp;13:3:00&nbsp;GMT+0800");<br />
　　　　Date&nbsp;day3=&nbsp;new&nbsp;Date(l);<br />
　　　　System.out.println("Day3's&nbsp;date(GMT)is:&nbsp;"+day3.toGMTString());<br />
　　　　System.out.println("Day3's&nbsp;date(Locale)is:&nbsp;"<br />
　　　　　+day3.toLocaleString());<br />
　　　　System.out.println("Day3's&nbsp;time&nbsp;zone&nbsp;offset&nbsp;is:"<br />
　　　　　+day3.getTimezoneOffset());<br />
　　　}<br />
　　}<br />
<br />
　　运行结果(JDK1.3版，与原文不同，原文是JDK1.0版)：<br />
　　E:\java\tutorial\java01&gt;java&nbsp;DateApp<br />
　　Today's&nbsp;date&nbsp;is&nbsp;Thu&nbsp;Dec&nbsp;27&nbsp;17:58:16&nbsp;CST&nbsp;2001<br />
　　Today's&nbsp;date(Internet&nbsp;GMT)is:27&nbsp;Dec&nbsp;2001&nbsp;09:58:16&nbsp;GMT<br />
　　Today's&nbsp;date(Locale)&nbsp;is:2001-12-27&nbsp;17:58:16<br />
　　Today's&nbsp;year&nbsp;is:&nbsp;101<br />
　　Today's&nbsp;month&nbsp;is:&nbsp;12<br />
　　Today's&nbsp;date&nbsp;is:&nbsp;27<br />
　　Day1's&nbsp;date&nbsp;is:&nbsp;Wed&nbsp;Feb&nbsp;23&nbsp;10:12:34&nbsp;CST&nbsp;2000<br />
　　Day2's&nbsp;date&nbsp;is:&nbsp;Fri&nbsp;Aug&nbsp;12&nbsp;13:03:00&nbsp;CST&nbsp;1996<br />
　　Day3's&nbsp;date(GMT)is:&nbsp;5&nbsp;Aug&nbsp;1996&nbsp;05:03:00&nbsp;GMT<br />
　　Day3's&nbsp;date(Locale)is:&nbsp;1996-8-5&nbsp;13:03:00<br />
　　Day3's&nbsp;time&nbsp;zone&nbsp;offset&nbsp;is:-480<br />
<br />
　　E:\java\tutorial\java01&gt;<br />
<br />
8.3&nbsp;日历类Calendar<br />
<br />
　　在早期的JDK版本中，日期(Date)类附有两大功能：(1)允许用年、月、日、时、分、秒来解释日期：(2)允许对表示日期的字符串进行格式化和句法分析。在JDK1.1中提供了类Calendar来完成第一种功能，类DateFormat来完成第二项功能。dateFormat是java.text包中的一个类。与Date类有所不同的是，DateFormat类接受用各种语言和不同习惯表示的日期字符串。本节将介绍java.util包中的类Calendar及其它新增加的相关的类。<br />
　　类Calendar是一个抽象类，它完成日期(Date)类和普通日期表示法(即用一组整型域如YEAR，MONTH，DAY，HOUR表示日期)之间的转换。<br />
　　由于所使用的规则不同，不同的日历系统对同一个日期的解释有所不同。在JDK1.1中提供了Calendar类一个子类GregorianCalendar??它实现了世界上普遍使用的公历系统。当然用户也可以通过继承Calendar类，并增加所需规则，以实现不同的日历系统。<br />
　　第GregorianCalendar继承了Calendar类。本节将在介绍类GregorianCalendar的同时顺带介绍Calendar类中的相关方法。<br />
　　类GregorianCalendar提供了七种构造函数：<br />
　　(1)public&nbsp;GregorianCalendar()<br />
　　创建的对象中的相关值被设置成指定时区，缺省地点的当前时间，即程序运行时所处的时区、地点的当前时间。<br />
　　(2)public&nbsp;GregorianCalendar(TimeZone&nbsp;zone)<br />
　　创建的对象中的相关值被设置成指定时区zone，缺省地点的当前时间。<br />
　　(3)public&nbsp;GregorianCalendar(Locale&nbsp;aLocale)<br />
　　创建的对象中的相关值被设置成缺省时区，指定地点aLocale的当前时间。<br />
　　(4)public&nbsp;GregorianCalendar(TimeZone&nbsp;zone,Local&nbsp;aLocale)<br />
　　创建的对象中的相关值被设置成指定时区，指定地点的当前时间。<br />
　　上面使用到的类TimeZone的性质如下：<br />
　　TimeZone是java.util包中的一个类，其中封装了有关时区的信息。每一个时区对应一组ID。类TimeZone提供了一些方法完成时区与对应ID两者之间的转换。<br />
　　(Ⅰ)已知某个特定的ID，可以调用方法<br />
　　public&nbsp;static&nbsp;synchronized&nbsp;TimeZone&nbsp;getTimeZone(String&nbsp;ID)<br />
来获取对应的时区对象。<br />
　　例&nbsp;太平洋时区的ID为PST，用下面的方法可获取对应于太平洋时区的时区对象：<br />
　　TimeZone&nbsp;tz=TimeZone.getTimeZone("PST");<br />
　　调用方法getDefault()可以获取主机所处时区的对象。<br />
　　TimeZone&nbsp;tz=TimeZone.getDefault();<br />
　　(Ⅱ)调用以下方法可以获取时区的ID<br />
　　■public&nbsp;static&nbsp;synchronized&nbsp;String[]&nbsp;getavailableIDs(int&nbsp;rawOffset)<br />
　　根据给定时区偏移值获取ID数组。同一时区的不同地区的ID可能不同，这是由于不同地区对是否实施夏时制意见不统一而造成的。<br />
　　例String&nbsp;s[]=TimeZone.getAvailableIDs(-7*60*60*1000);<br />
　　打印s，结果为s[0]=PNT，s[1]=MST<br />
　　■public&nbsp;static&nbsp;synchronized&nbsp;String[]&nbsp;getAvailableIDs()<br />
　　获取提供的所有支持的ID。<br />
　　■public&nbsp;String&nbsp;getID()<br />
　　获取特定时区对象的ID。<br />
　　例&nbsp;TimeZone&nbsp;tz=TimeZone.getDefault();<br />
　　String&nbsp;s=tz.getID();<br />
　　打印s，结果为s=CTT。<br />
　　上面使用类的对象代表了一个特定的地理、政治或文化区域。Locale只是一种机制，它用来标识一类对象，Local本身并不包含此类对象。<br />
　　要获取一个Locale的对象有两种方法：<br />
　　(Ⅰ)调用Locale类的构造方法<br />
　　Locale(String&nbsp;language,String&nbsp;country)<br />
　　Locale(String&nbsp;language,String&nbsp;country,String&nbsp;variant)<br />
　　参数说明：language??在ISO-639中定义的代码，由两个小写字母组成。<br />
　　　　　　　country??在ISO-3166中定义的代码，由两个大写字母组成。<br />
　　　　　　　variant??售货商以及特定浏览器的代码，例如使用WIN代表Windows。<br />
　　(Ⅱ)调用Locale类中定义的常量<br />
　　Local类提供了大量的常量供用户创建Locale对象。<br />
　　例&nbsp;Locale.CHINA<br />
　　　　为中国创建一个Locale的对象。<br />
　　类TimeZone和类Locale中的其它方法，读者可查阅API。<br />
　　(5)public&nbsp;GregorianCalendar(int&nbsp;year,int&nbsp;month,int&nbsp;date)<br />
　　(6)public&nbsp;GregorianCalendar(int&nbsp;year,int&nbsp;month,int&nbsp;date,int&nbsp;hour,int&nbsp;minute)<br />
　　(7)public&nbsp;GregorianCalendar(int&nbsp;year,int&nbsp;month,int&nbsp;date,int&nbsp;hour,int&nbsp;minute,int&nbsp;second)<br />
　　用给定的日期和时间创建一个GregorianCalendar的对象。<br />
　　参数说明：<br />
　　year-设定日历对象的变量YEAR；month-设定日历对象的变量MONTH；<br />
　　date-设定日历对象的变量DATE；hour-设定日历对象的变量HOUR_OF_DAY；<br />
　　minute-设定日历对象的变量MINUTE；second-设定日历对象的变量SECOND。<br />
　　与Date类中不同的是year的值没有1900这个下限，而且year的值代表实际的年份。month的含义与Date类相同，0代表1月，11代表12月。<br />
　　例&nbsp;GregorianCalendar&nbsp;cal=new&nbsp;GregorianCalendar(1991,2,4)<br />
　　cal的日期为1991年3月4号。<br />
　　除了与Date中类似的方法外，Calendar类还提供了有关方法对日历进行滚动计算和数学计算。计算规则由给定的日历系统决定。进行日期计算时，有时会遇到信息不足或信息不实等特殊情况。Calendar采取了相应的方法解决这些问题。当信息不足时将采用缺省设置，在GregorianCalendar类中缺省设置一般为YEAR=1970,MONTH=JANUARY,DATE=1。<br />
　　当信息不实时，Calendar将按下面的次序优先选择相应的Calendar的变量组合，并将其它有冲突的信息丢弃。<br />
　　MONTH+DAY_OF_MONTH<br />
　　MONTH+WEEK_OF_MONTH+DAY_OF_WEEK<br />
　　MONTH+DAY_OF_WEEK_OF_MONTH+DAY_OF_WEEK<br />
　　DAY_OF+YEAR<br />
　　DAY_OF_WEEK_WEEK_OF_YEAR<br />
　　HOUR_OF_DAY<br />
<br />
8.4&nbsp;随机数类Random<br />
<br />
　　Java实用工具类库中的类java.util.Random提供了产生各种类型随机数的方法。它可以产生int、long、float、double以及Goussian等类型的随机数。这也是它与java.lang.Math中的方法Random()最大的不同之处，后者只产生double型的随机数。<br />
　　类Random中的方法十分简单，它只有两个构造方法和六个普通方法。<br />
　　构造方法：<br />
　　(1)public&nbsp;Random()<br />
　　(2)public&nbsp;Random(long&nbsp;seed)<br />
　　Java产生随机数需要有一个基值seed，在第一种方法中基值缺省，则将系统时间作为seed。<br />
　　普通方法：<br />
　　(1)public&nbsp;synonronized&nbsp;void&nbsp;setSeed(long&nbsp;seed)<br />
　　该方法是设定基值seed。<br />
　　(2)public&nbsp;int&nbsp;nextInt()<br />
　　该方法是产生一个整型随机数。<br />
　　(3)public&nbsp;long&nbsp;nextLong()<br />
　　该方法是产生一个long型随机数。<br />
　　(4)public&nbsp;float&nbsp;nextFloat()<br />
　　该方法是产生一个Float型随机数。<br />
　　(5)public&nbsp;double&nbsp;nextDouble()<br />
　　该方法是产生一个Double型随机数。<br />
　　(6)public&nbsp;synchronized&nbsp;double&nbsp;nextGoussian()<br />
　　该方法是产生一个double型的Goussian随机数。<br />
　　例8.2&nbsp;RandomApp.java。<br />
　　//import&nbsp;java.lang.*;<br />
　　import&nbsp;java.util.Random;<br />
<br />
　　public&nbsp;class&nbsp;RandomApp{<br />
　　　public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;args[]){<br />
　　　　Random&nbsp;ran1=new&nbsp;Random();<br />
　　　　Random&nbsp;ran2=new&nbsp;Random(12345);<br />
　　　　//创建了两个类Random的对象。<br />
　　　　System.out.println("The&nbsp;1st&nbsp;set&nbsp;of&nbsp;random&nbsp;numbers:");<br />
　　　　System.out.println("\t&nbsp;Integer:"+ran1.nextInt());<br />
　　　　System.out.println("\t&nbsp;Long:"+ran1.nextLong());<br />
　　　　System.out.println("\t&nbsp;Float:"+ran1.nextFloat());<br />
　　　　System.out.println("\t&nbsp;Double:"+ran1.nextDouble());<br />
　　　　System.out.println("\t&nbsp;Gaussian:"+ran1.nextGaussian());<br />
　　　　//产生各种类型的随机数<br />
　　　　System.out.print("The&nbsp;2nd&nbsp;set&nbsp;of&nbsp;random&nbsp;numbers:");<br />
　　　　for(int&nbsp;i=0;i&lt;5;i++){<br />
　　　　　System.out.println(ran2.nextInt()+"&nbsp;");<br />
　　　　　if(i==2)&nbsp;System.out.println();<br />
　　　　　//产生同种类型的不同的随机数。<br />
　　　　　System.out.println();//原文如此<br />
　　　　}<br />
　　　}<br />
　　}<br />
<br />
　　运行结果：<br />
　　E:\java01&gt;java&nbsp;RandomApp<br />
　　The&nbsp;1st&nbsp;set&nbsp;of&nbsp;random&nbsp;numbers:<br />
　　　　Integer:-173899656<br />
　　　　Long:8056223819738127077<br />
　　　　Float:0.6293638<br />
　　　　Double:0.7888394520265607<br />
　　　　Gaussian:0.5015701094568733<br />
　　The&nbsp;2nd&nbsp;set&nbsp;of&nbsp;random&nbsp;numbers:1553932502<br />
　　-2090749135<br />
　　-287790814<br />
　　-355989640<br />
　　-716867186<br />
　　E:\java01&gt;<br />
<br />
8.5&nbsp;向量类Vector<br />
<br />
　　Java.util.Vector提供了向量(Vector)类以实现类似动态数组的功能。在Java语言中。正如在一开始就提到过，是没有指针概念的，但如果能正确灵活地使用指针又确实可以大大提高程序的质量，比如在C、C++中所谓"动态数组"一般都由指针来实现。为了弥补这点缺陷，Java提供了丰富的类库来方便编程者使用，Vector类便是其中之一。事实上，灵活使用数组也可完成向量类的功能，但向量类中提供的大量方法大大方便了用户的使用。<br />
　　创建了一个向量类的对象后，可以往其中随意地插入不同的类的对象，既不需顾及类型也不需预先选定向量的容量，并可方便地进行查找。对于预先不知或不愿预先定义数组大小，并需频繁进行查找、插入和删除工作的情况，可以考虑使用向量类。<br />
　　向量类提供了三种构造方法：<br />
　　public&nbsp;vector()<br />
　　public&nbsp;vector(int&nbsp;initialcapacity,int&nbsp;capacityIncrement)<br />
　　public&nbsp;vector(int&nbsp;initialcapacity)<br />
　　使用第一种方法，系统会自动对向量对象进行管理。若使用后两种方法，则系统将根据参数initialcapacity设定向量对象的容量(即向量对象可存储数据的大小)，当真正存放的数据个数超过容量时，系统会扩充向量对象的存储容量。参数capacityIncrement给定了每次扩充的扩充值。当capacityIncrement为0时，则每次扩充一倍。利用这个功能可以优化存储。<br />
　　在Vector类中提供了各种方法方便用户使用：<br />
　　■插入功能<br />
　　(1)public&nbsp;final&nbsp;synchronized&nbsp;void&nbsp;addElement(Object&nbsp;obj)<br />
　　将obj插入向量的尾部。obj可以是任何类的对象。对同一个向量对象，可在其中插入不同类的对象。但插入的应是对象而不是数值，所以插入数值时要注意将数值转换成相应的对象。<br />
　　例&nbsp;要插入一个整数1时，不要直接调用v1.addElement(1)，正确的方法为：<br />
　　Vector&nbsp;v1=new&nbsp;Vector();<br />
　　Integer&nbsp;integer1=new&nbsp;Integer(1);<br />
　　v1.addElement(integer1);<br />
　　(2)public&nbsp;final&nbsp;synchronized&nbsp;void&nbsp;setElementAt(object&nbsp;obj,int&nbsp;index)<br />
　　将index处的对象设成obj，原来的对象将被覆盖。<br />
　　(3)public&nbsp;final&nbsp;synchronized&nbsp;void&nbsp;insertElementAt(Object&nbsp;obj,int&nbsp;index)<br />
　　在index指定的位置插入obj，原来对象以及此后的对象依次往后顺延。<br />
　　■删除功能<br />
　　(1)public&nbsp;final&nbsp;synchronized&nbsp;void&nbsp;removeElement(Object&nbsp;obj)<br />
　　从向量中删除obj。若有多个存在，则从向量头开始试，删除找到的第一个与obj相同的向量成员。<br />
　　(2)public&nbsp;final&nbsp;synchronized&nbsp;void&nbsp;removeAllElement()<br />
　　删除向量中所有的对象。<br />
　　(3)public&nbsp;final&nbsp;synchronized&nbsp;void&nbsp;removeElementlAt(int&nbsp;index)<br />
　　删除index所指的地方的对象。<br />
　　■查询搜索功能<br />
　　(1)public&nbsp;final&nbsp;int&nbsp;indexOf(Object&nbsp;obj)<br />
　　从向量头开始搜索obj&nbsp;,返回所遇到的第一个obj对应的下标，若不存在此obj，返回-1。<br />
　　(2)public&nbsp;final&nbsp;synchronized&nbsp;int&nbsp;indexOf(Object&nbsp;obj,int&nbsp;index)<br />
　　从index所表示的下标处开始搜索obj。<br />
　　(3)public&nbsp;final&nbsp;int&nbsp;lastIndexOf(Object&nbsp;obj)<br />
　　从向量尾部开始逆向搜索obj。<br />
　　(4)public&nbsp;final&nbsp;synchronized&nbsp;int&nbsp;lastIndexOf(Object&nbsp;obj,int&nbsp;index)<br />
　　从index所表示的下标处由尾至头逆向搜索obj。<br />
　　(5)public&nbsp;final&nbsp;synchronized&nbsp;Object&nbsp;firstElement()<br />
　　获取向量对象中的首个obj。<br />
　　(6)public&nbsp;final&nbsp;synchronized&nbsp;Object&nbsp;lastelement()<br />
　　获取向量对象中的最后一个obj。<br />
　　了解了向量的最基本的方法后，我们来看一下例8.3VectorApp.java。<br />
　　例8.3&nbsp;VectorApp.java。<br />
　　import&nbsp;java.util.Vector;<br />
　　import&nbsp;java.lang.*;//这一句不应该要，但原文如此<br />
　　import&nbsp;java.util.Enumeration;<br />
　　public&nbsp;class&nbsp;VectorApp{<br />
　　　public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args){<br />
　　　　Vector&nbsp;v1=new&nbsp;Vector();<br />
　　　　Integer&nbsp;integer1=new&nbsp;Integer(1);<br />
　　　　v1.addElement("one");<br />
　　　　//加入的为字符串对象<br />
　　　　v1.addElement(integer1);<br />
　　　　v1.addElement(integer1);<br />
　　　　//加入的为Integer的对象<br />
　　　　v1.addElement("two");<br />
　　　　v1.addElement(new&nbsp;Integer(2));<br />
　　　　v1.addElement(integer1);<br />
　　　　v1.addElement(integer1);<br />
　　　　System.out.println("The&nbsp;vector&nbsp;v1&nbsp;is:\n\t"+v1);<br />
　　　　//将v1转换成字符串并打印<br />
　　　　v1.insertElementAt("three",2);<br />
　　　　v1.insertElementAt(new&nbsp;Float(3.9),3);<br />
　　　　System.out.println("The&nbsp;vector&nbsp;v1(used&nbsp;method&nbsp;insertElementAt())&nbsp;is:\n\t&nbsp;"+v1);<br />
　　　　//往指定位置插入新的对象，指定位置后的对象依次往后顺延<br />
　　　　v1.setElementAt("four",2);<br />
　　　　System.out.println("The&nbsp;vector&nbsp;v1(used&nbsp;method&nbsp;setElementAt())&nbsp;is:\n\t&nbsp;"+v1);<br />
　　　　//将指定位置的对象设置为新的对象<br />
　　　　v1.removeElement(integer1);<br />
　　　　//从向量对象v1中删除对象integer1由于存在多个integer1所以从头开始<br />
　　　　//找，删除找到的第一个integer1<br />
　　　　Enumeration&nbsp;enum=v1.elements();<br />
　　　　System.out.print("The&nbsp;vector&nbsp;v1(used&nbsp;method&nbsp;removeElement())is:");<br />
　　　　while(enum.hasMoreElements())<br />
　　　　System.out.print(enum.nextElement()+"&nbsp;");<br />
　　　　System.out.println();<br />
　　　　//使用枚举类(Enumeration)的方法来获取向量对象的每个元素<br />
　　　　System.out.println("The&nbsp;position&nbsp;of&nbsp;object&nbsp;1(top-to-bottom):"<br />
　　　　　+&nbsp;v1.indexOf(integer1));<br />
　　　　System.out.println("The&nbsp;position&nbsp;of&nbsp;object&nbsp;1(tottom-to-top):"<br />
　　　　　+v1.lastIndexOf(integer1));<br />
　　　　//按不同的方向查找对象integer1所处的位置<br />
　　　　v1.setSize(4);<br />
　　　　System.out.println("The&nbsp;new&nbsp;vector(resized&nbsp;the&nbsp;vector)is:"+v1);<br />
　　　　//重新设置v1的大小，多余的元素被行弃<br />
　　　}<br />
　　}<br />
　　运行结果：<br />
　　E:\java01&gt;java&nbsp;VectorApp<br />
　　The&nbsp;vector&nbsp;v1&nbsp;is:<br />
　　　　　[one,&nbsp;1,&nbsp;1,&nbsp;two,&nbsp;2,&nbsp;1,&nbsp;1]<br />
　　The&nbsp;vector&nbsp;v1(used&nbsp;method&nbsp;insertElementAt())&nbsp;is:<br />
　　　　　[one,&nbsp;1,&nbsp;three,&nbsp;3.9,&nbsp;1,&nbsp;two,&nbsp;2,&nbsp;1,&nbsp;1]<br />
　　The&nbsp;vector&nbsp;v1(used&nbsp;method&nbsp;setElementAt())&nbsp;is:<br />
　　　　　[one,&nbsp;1,&nbsp;four,&nbsp;3.9,&nbsp;1,&nbsp;two,&nbsp;2,&nbsp;1,&nbsp;1]<br />
　　The&nbsp;vector&nbsp;v1(used&nbsp;method&nbsp;removeElement())is:one&nbsp;four&nbsp;3.9&nbsp;1&nbsp;two&nbsp;2&nbsp;1&nbsp;1<br />
　　The&nbsp;position&nbsp;of&nbsp;object&nbsp;1(top-to-bottom):3<br />
　　The&nbsp;position&nbsp;of&nbsp;object&nbsp;1(tottom-to-top):7<br />
　　The&nbsp;new&nbsp;vector(resized&nbsp;the&nbsp;vector)is:[one,&nbsp;four,&nbsp;3.9,&nbsp;1]<br />
　　E:\java01&gt;<br />
　　从例8.3运行的结果中可以清楚地了解上面各种方法的作用，另外还有几点需解释。<br />
　　(1)类Vector定义了方法<br />
　　public&nbsp;final&nbsp;int&nbsp;size()<br />
　　此方法用于获取向量元素的个数。它的返回值是向是中实际存在的元素个数，而非向量容量。可以调用方法capactly()来获取容量值。<br />
　　方法：<br />
　　public&nbsp;final&nbsp;synchronized&nbsp;void&nbsp;setsize(int&nbsp;newsize)<br />
　　此方法用来定义向量大小。若向量对象现有成员个数已超过了newsize的值，则超过部分的多余元素会丢失。<br />
　　(2)程序中定义了Enumeration类的一个对象<br />
　　Enumeration是java.util中的一个接口类，在Enumeration中封装了有关枚举数据集合的方法。<br />
　　在Enumeration中提供了方法hawMoreElement()来判断集合中是束还有其它元素和方法nextElement()来获取下一个元素。利用这两个方法可以依次获得集合中元素。<br />
　　Vector中提供方法：<br />
　　public&nbsp;final&nbsp;synchronized&nbsp;Enumeration&nbsp;elements()<br />
　　此方法将向量对象对应到一个枚举类型。java.util包中的其它类中也大都有这类方法，以便于用户获取对应的枚举类型。<br />
<br />
8.6&nbsp;栈类Stack<br />
<br />
　　Stack类是Vector类的子类。它向用户提供了堆栈这种高级的数据结构。栈的基本特性就是先进后出。即先放入栈中的元素将后被推出。Stack类中提供了相应方法完成栈的有关操作。<br />
　　基本方法：<br />
　　public&nbsp;Object&nbsp;push(Object&nbsp;Hem)<br />
　　将Hem压入栈中，Hem可以是任何类的对象。<br />
　　public&nbsp;Object&nbsp;pop()<br />
　　弹出一个对象。<br />
　　public&nbsp;Object&nbsp;peek()<br />
　　返回栈顶元素，但不弹出此元素。<br />
　　public&nbsp;int&nbsp;search(Object&nbsp;obj)<br />
　　搜索对象obj,返回它所处的位置。<br />
　　public&nbsp;boolean&nbsp;empty()<br />
　　判别栈是否为空。<br />
　　例8.4&nbsp;StackApp.java使用了上面的各种方法。<br />
　　例8.4&nbsp;StackApp.java。<br />
　　import&nbsp;java.lang.*;<br />
　　import&nbsp;java.util.*;<br />
　　public&nbsp;class&nbsp;StackApp{<br />
　　　public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;args[]){<br />
　　　　Stack&nbsp;sta=new&nbsp;Stack();<br />
　　　　sta.push("Apple");<br />
　　　　sta.push("banana");<br />
　　　　sta.push("Cherry");<br />
　　　　//压入的为字符串对象<br />
　　　　sta.push(new&nbsp;Integer(2));<br />
　　　　//压入的为Integer的对象，值为2<br />
　　　　sta.push(new&nbsp;Float(3.5));<br />
　　　　//压入的为Float的对象，值为3.5<br />
　　　　System.out.println("The&nbsp;stack&nbsp;is,"+sta);<br />
　　　　//对应栈sta<br />
　　　　System.out.println("The&nbsp;top&nbsp;of&nbsp;stack&nbsp;is:"+sta.peek());<br />
　　　　//对应栈顶元素，但不将此元素弹出<br />
　　　　System.out.println("The&nbsp;position&nbsp;of&nbsp;object&nbsp;Cherry&nbsp;is:"<br />
　　　　+sta.search("cherry"));<br />
　　　　//打印对象Cherry所处的位置<br />
　　　　System.out.print("Pop&nbsp;the&nbsp;element&nbsp;of&nbsp;the&nbsp;stack:");<br />
　　　　while(!sta.empty())<br />
　　　　System.out.print(sta.pop()+"&nbsp;");<br />
　　　　System.out.println();<br />
　　　　//将栈中的元素依次弹出并打印。与第一次打印的sta的结果比较，可看出栈<br />
　　　　//先进后出的特点<br />
　　　}<br />
　　}<br />
　　运行结果(略)<br />
<br />
<br />
8.7&nbsp;哈希表类Hashtable<br />
<br />
　　哈希表是一种重要的存储方式，也是一种常见的检索方法。其基本思想是将关系码的值作为自变量，通过一定的函数关系计算出对应的函数值，把这个数值解释为结点的存储地址，将结点存入计算得到存储地址所对应的存储单元。检索时采用检索关键码的方法。现在哈希表有一套完整的算法来进行插入、删除和解决冲突。在Java中哈希表用于存储对象，实现快速检索。<br />
　　Java.util.Hashtable提供了种方法让用户使用哈希表，而不需要考虑其哈希表真正如何工作。<br />
　　哈希表类中提供了三种构造方法，分别是：<br />
　　public&nbsp;Hashtable()<br />
　　public&nbsp;Hashtable(int&nbsp;initialcapacity)<br />
　　public&nbsp;Hashtable(int&nbsp;initialCapacity,float&nbsp;loadFactor)<br />
　　参数initialCapacity是Hashtable的初始容量，它的值应大于0。loadFactor又称装载因子，是一个0.0到0.1之间的float型的浮点数。它是一个百分比，表明了哈希表何时需要扩充，例如，有一哈希表，容量为100，而装载因子为0.9，那么当哈希表90%的容量已被使用时，此哈希表会自动扩充成一个更大的哈希表。如果用户不赋这些参数，系统会自动进行处理，而不需要用户操心。<br />
　　Hashtable提供了基本的插入、检索等方法。<br />
　　■插入<br />
　　public&nbsp;synchronized&nbsp;void&nbsp;put(Object&nbsp;key,Object&nbsp;value)<br />
给对象value设定一关键字key,并将其加到Hashtable中。若此关键字已经存在，则将此关键字对应的旧对象更新为新的对象Value。这表明在哈希表中相同的关键字不可能对应不同的对象(从哈希表的基本思想来看，这也是显而易见的)。<br />
　　■检索<br />
　　public&nbsp;synchronized&nbsp;Object&nbsp;get(Object&nbsp;key)<br />
　　根据给定关键字key获取相对应的对象。<br />
　　public&nbsp;synchronized&nbsp;boolean&nbsp;containsKey(Object&nbsp;key)<br />
　　判断哈希表中是否包含关键字key。<br />
　　public&nbsp;synchronized&nbsp;boolean&nbsp;contains(Object&nbsp;value)<br />
　　判断value是否是哈希表中的一个元素。<br />
　　■删除<br />
　　public&nbsp;synchronized&nbsp;object&nbsp;remove(object&nbsp;key)<br />
　　从哈希表中删除关键字key所对应的对象。<br />
　　public&nbsp;synchronized&nbsp;void&nbsp;clear()<br />
　　清除哈希表<br />
　　另外，Hashtalbe还提供方法获取相对应的枚举集合：<br />
　　public&nbsp;synchronized&nbsp;Enumeration&nbsp;keys()<br />
　　返回关键字对应的枚举对象。<br />
　　public&nbsp;synchronized&nbsp;Enumeration&nbsp;elements()<br />
　　返回元素对应的枚举对象。<br />
　　例8.5&nbsp;Hashtable.java给出了使用Hashtable的例子。<br />
　　例8.5&nbsp;Hashtalbe.java。<br />
　　//import&nbsp;java.lang.*;<br />
　　import&nbsp;java.util.Hashtable;<br />
　　import&nbsp;java.util.Enumeration;<br />
　　public&nbsp;class&nbsp;HashApp{<br />
　　　public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;args[]){<br />
　　　　Hashtable&nbsp;hash=new&nbsp;Hashtable(2,(float)0.8);<br />
　　　　//创建了一个哈希表的对象hash，初始容量为2，装载因子为0.8<br />
<br />
　　　　hash.put("Jiangsu","Nanjing");<br />
　　　　//将字符串对象"Jiangsu"给定一关键字"Nanjing",并将它加入hash<br />
　　　　hash.put("Beijing","Beijing");<br />
　　　　hash.put("Zhejiang","Hangzhou");<br />
<br />
　　　　System.out.println("The&nbsp;hashtable&nbsp;hash1&nbsp;is:&nbsp;"+hash);<br />
　　　　System.out.println("The&nbsp;size&nbsp;of&nbsp;this&nbsp;hash&nbsp;table&nbsp;is&nbsp;"+hash.size());<br />
　　　　//打印hash的内容和大小<br />
<br />
　　　　Enumeration&nbsp;enum1=hash.elements();<br />
　　　　System.out.print("The&nbsp;element&nbsp;of&nbsp;hash&nbsp;is:&nbsp;");<br />
　　　　while(enum1.hasMoreElements())<br />
　　　　　System.out.print(enum1.nextElement()+"&nbsp;");<br />
　　　　System.out.println();<br />
　　　　//依次打印hash中的内容<br />
　　　　if(hash.containsKey("Jiangsu"))<br />
　　　　　System.out.println("The&nbsp;capatial&nbsp;of&nbsp;Jiangsu&nbsp;is&nbsp;"+hash.get("Jiangsu"));<br />
　　　　hash.remove("Beijing");<br />
　　　　//删除关键字Beijing对应对象<br />
　　　　System.out.println("The&nbsp;hashtable&nbsp;hash2&nbsp;is:&nbsp;"+hash);<br />
　　　　System.out.println("The&nbsp;size&nbsp;of&nbsp;this&nbsp;hash&nbsp;table&nbsp;is&nbsp;"+hash.size());<br />
　　　}<br />
　　}<br />
<br />
　　运行结果：<br />
　　The&nbsp;hashtable&nbsp;hash1&nbsp;is:&nbsp;{Beijing=Beijing,&nbsp;Zhejiang=Hangzhou,&nbsp;Jiangsu=Nanjing}<br />
　　The&nbsp;size&nbsp;of&nbsp;this&nbsp;hash&nbsp;table&nbsp;is&nbsp;3<br />
　　The&nbsp;element&nbsp;of&nbsp;hash&nbsp;is:&nbsp;Beijing&nbsp;Hangzhou&nbsp;Nanjing<br />
　　The&nbsp;capatial&nbsp;of&nbsp;Jiangsu&nbsp;is&nbsp;Nanjing<br />
　　The&nbsp;hashtable&nbsp;hash2&nbsp;is:&nbsp;{Zhejiang=Hangzhou,&nbsp;Jiangsu=Nanjing}<br />
　　The&nbsp;size&nbsp;of&nbsp;this&nbsp;hash&nbsp;table&nbsp;is&nbsp;2<br />
<br />
　　Hashtable是Dictionary(字典)类的子类。在字典类中就把关键字对应到数据值。字典类是一个抽象类。在java.util中还有一个类Properties，它是Hashtable的子类。用它可以进行与对象属性相关的操作。<br />
<br />
8.8&nbsp;位集合类BitSet<br />
<br />
　　位集合类中封装了有关一组二进制数据的操作。<br />
　　我们先来看一下例8.6&nbsp;BitSetApp.java。<br />
　　例8.6&nbsp;BitSetApp.java<br />
　　//import&nbsp;java.lang.*;<br />
　　import&nbsp;java.util.BitSet;<br />
　　public&nbsp;class&nbsp;BitSetApp{<br />
　　　private&nbsp;static&nbsp;int&nbsp;n=5;<br />
　　　public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args){<br />
　　　　BitSet&nbsp;set1=new&nbsp;BitSet(n);<br />
　　　　for(int&nbsp;i=0;i&lt;n;i++)&nbsp;set1.set(i);<br />
　　　　//将set1的各位赋1，即各位均为true<br />
　　　　BitSet&nbsp;set2=&nbsp;new&nbsp;BitSet();<br />
　　　　set2=(BitSet)set1.clone();<br />
　　　　//set2为set1的拷贝<br />
　　　　set1.clear(0);<br />
　　　　set2.clear(2);<br />
　　　　//将set1的第0位set2的第2位清零<br />
　　　　System.out.println("The&nbsp;set1&nbsp;is:&nbsp;"+set1);<br />
　　　　//直接将set1转换成字符串输出，输出的内容是set1中值true所处的位置<br />
　　　　//打印结果为The&nbsp;set1&nbsp;is:{1,2,3,4}<br />
　　　　System.out.println("The&nbsp;hash&nbsp;code&nbsp;of&nbsp;set2&nbsp;is:&nbsp;"+set2.hashCode());<br />
　　　　//打印set2的hashCode<br />
　　　　printbit("set1",set1);<br />
　　　　printbit("set2",set2);<br />
　　　　//调用打印程序printbit(),打印对象中的每一个元素<br />
　　　　//打印set1的结果为The&nbsp;bit&nbsp;set1&nbsp;is:&nbsp;false&nbsp;true&nbsp;true&nbsp;true&nbsp;true<br />
　　　　set1.and(set2);<br />
　　　　printbit("set1&nbsp;and&nbsp;set2",set1);<br />
　　　　//完成set1&nbsp;and&nbsp;set2,并打印结果<br />
　　　　set1.or(set2);<br />
　　　　printbit("set1&nbsp;or&nbsp;set2",set1);<br />
　　　　//完成set1&nbsp;or&nbsp;set2,并打印结果<br />
　　　　set1.xor(set2);<br />
　　　　printbit("set1&nbsp;xor&nbsp;set2",set1);<br />
　　　　//完成set1&nbsp;xor&nbsp;set2,并打印结果<br />
　　　}<br />
　　　//打印BitSet对象中的内容<br />
　　　public&nbsp;static&nbsp;void&nbsp;printbit(String&nbsp;name,BitSet&nbsp;set){<br />
　　　　System.out.print("The&nbsp;bit&nbsp;"+name+"&nbsp;is:&nbsp;");<br />
　　　　for(int&nbsp;i=0;i&lt;n;i++)<br />
　　　　　System.out.print(set.get(i)+"&nbsp;");<br />
　　　　System.out.println();<br />
　　　}<br />
　　}<br />
<br />
　　运行结果：<br />
　　The&nbsp;set1&nbsp;is:&nbsp;{1,&nbsp;2,&nbsp;3,&nbsp;4}<br />
　　The&nbsp;hash&nbsp;code&nbsp;of&nbsp;set2&nbsp;is:&nbsp;1225<br />
　　The&nbsp;bit&nbsp;set1&nbsp;is:&nbsp;false&nbsp;true&nbsp;true&nbsp;true&nbsp;true<br />
　　The&nbsp;bit&nbsp;set2&nbsp;is:&nbsp;true&nbsp;true&nbsp;false&nbsp;true&nbsp;true<br />
　　The&nbsp;bit&nbsp;set1&nbsp;and&nbsp;set2&nbsp;is:&nbsp;false&nbsp;true&nbsp;false&nbsp;true&nbsp;true<br />
　　The&nbsp;bit&nbsp;set1&nbsp;or&nbsp;set2&nbsp;is:&nbsp;true&nbsp;true&nbsp;false&nbsp;true&nbsp;true<br />
　　The&nbsp;bit&nbsp;set1&nbsp;xor&nbsp;set2&nbsp;is:&nbsp;false&nbsp;false&nbsp;false&nbsp;false&nbsp;false<br />
<br />
　　程序中使用了BitSet类提供的两种构造方法：<br />
　　　　public&nbsp;BitSet();<br />
　　　　public&nbsp;BitSet(int&nbsp;n);<br />
　　参数n代表所创建的BitSet类的对象的大小。BitSet类的对象的大小在必要时会由系统自动扩充。<br />
　　其它方法：<br />
　　public&nbsp;void&nbsp;set(int&nbsp;n)<br />
　　将BitSet对象的第n位设置成1。<br />
　　public&nbsp;void&nbsp;clear(int&nbsp;n)<br />
　　将BitSet对象的第n位清零。<br />
　　public&nbsp;boolean&nbsp;get(int&nbsp;n)<br />
　　读取位集合对象的第n位的值，它获取的是一个布尔值。当第n位为1时，返回true；第n位为0时，返回false。<br />
　　另外，如在程序中所示，当把一BitSet类的对象转换成字符串输出时，输出的内容是此对象中true所处的位置。<br />
　　在BitSet中提供了一组位操作，分别是：<br />
　　public&nbsp;void&nbsp;and(BitSet&nbsp;set)<br />
　　public&nbsp;void&nbsp;or(BitSet&nbsp;set)<br />
　　public&nbsp;void&nbsp;xor(BitSet&nbsp;set)<br />
利用它们可以完成两个位集合之间的与、或、异或操作。<br />
　　BitSet类中有一方法public&nbsp;int&nbsp;size()来取得位集合的大小，它的返回值与初始化时设定的位集合大小n不一样，一般为64。<br />
<br />
小结<br />
<br />
　　本章我们介绍了Java的实用工具类库java.util中一些常用的类。java.util包中还有其它一些类。它们的具体用法用户可以自行查阅API。在下一章，我们将学习利用java.awt包进行窗口程序设计。在下章的例子中我们将使用到本章介绍的各种类。&nbsp;&nbsp;</span></p>
</span></span>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311977.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:36 <a href="http://www.blogjava.net/JeromeKwok/articles/311977.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用J2SEAPI读取Properties文件的六种方法</title><link>http://www.blogjava.net/JeromeKwok/articles/311976.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:34:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311976.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311976.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311976.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311976.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311976.html</trackback:ping><description><![CDATA[<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New"><span style="font-size: 10pt">&nbsp; </p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">使用J2SEAPI读取Properties文件的六种方法</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">1。使用java.util.Properties类的load()方法</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">示例：InputStreamin=lnewBufferedInputStream(newFileInputStream(name));</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">Propertiesp=newProperties();</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">p.load(in);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">2。使用java.util.ResourceBundle类的getBundle()方法</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">示例：ResourceBundlerb=ResourceBundle.getBundle(name,Locale.getDefault());</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">3。使用java.util.PropertyResourceBundle类的构造函数</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">示例：InputStreamin=newBufferedInputStream(newFileInputStream(name));</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">ResourceBundlerb=newPropertyResourceBundle(in);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">4。使用class变量的getResourceAsStream()方法</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">示例：InputStreamin=JProperties.class.getResourceAsStream(name);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">Propertiesp=newProperties();</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">p.load(in);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">5。使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">示例：InputStreamin=JProperties.class.getClassLoader().getResourceAsStream(name);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">Propertiesp=newProperties();</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">p.load(in);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">6。使用java.lang.ClassLoader类的getSystemResourceAsStream()静态方法</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">示例：InputStreamin=ClassLoader.getSystemResourceAsStream(name);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">Propertiesp=newProperties();</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">p.load(in);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">补充</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">Servlet中可以使用javax.servlet.ServletContext的getResourceAsStream()方法</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">示例：InputStreamin=context.getResourceAsStream(path);</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">Propertiesp=newProperties();</span></p>
<p style="text-indent: 2em" mce_style="TEXT-INDENT: 2em"><span style="font-family: Courier New">p.load(in);</span></p>
<p><span style="font-family: Courier New">&nbsp;</span></p>
</span></span>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:34 <a href="http://www.blogjava.net/JeromeKwok/articles/311976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java反射经典实例 Java Reflection Cookbook </title><link>http://www.blogjava.net/JeromeKwok/articles/311975.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:32:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311975.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311975.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311975.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311975.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311975.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; Java提供了一套机制来动态执行方法和构造方法，以及数组操作等，这套机制就叫——反射。反射机制是如今很多流行框架的实现基础，其中包括Spring、Hibernate等。原理性的问题不是本文的重点，接下来让我们在实例中学习这套精彩的机制。1. 得到某个对象的属性&nbsp;Code highlighting produced by Actipro CodeH...&nbsp;&nbsp;<a href='http://www.blogjava.net/JeromeKwok/articles/311975.html'>阅读全文</a><img src ="http://www.blogjava.net/JeromeKwok/aggbug/311975.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:32 <a href="http://www.blogjava.net/JeromeKwok/articles/311975.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA对数字证书的常用操作</title><link>http://www.blogjava.net/JeromeKwok/articles/311973.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:29:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311973.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311973.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311973.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311973.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311973.html</trackback:ping><description><![CDATA[<p><span style="font-family: Courier New"><span style="font-size: 10pt">&nbsp; </p>
<p><span style="font-family: Courier New">一：需要包含的包<br />
&nbsp;&nbsp;&nbsp; import java.security.*;<br />
&nbsp;&nbsp;&nbsp; import java.io.*;<br />
&nbsp;&nbsp;&nbsp; import java.util.*;<br />
&nbsp;&nbsp;&nbsp; import java.security.*;<br />
&nbsp;&nbsp;&nbsp; import java.security.cert.*;<br />
&nbsp;&nbsp;&nbsp; import sun.security.x509.*<br />
&nbsp;&nbsp;&nbsp; import java.security.cert.Certificate;<br />
&nbsp;&nbsp;&nbsp; import java.security.cert.CertificateFactory;</span></p>
<p><span style="font-family: Courier New">二：从文件中读取证书<br />
&nbsp;&nbsp;&nbsp; 用keytool将.keystore中的证书写入文件中，然后从该文件中读取证书信息<br />
&nbsp;&nbsp;&nbsp; CertificateFactory cf=CertificateFactory.getInstance("X.509");<br />
&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream("out.csr");<br />
&nbsp;&nbsp;&nbsp; Certificate c=cf.generateCertificate(in);</span></p>
<p><span style="font-family: Courier New">&nbsp;&nbsp;&nbsp; String s=c.toString();<br />
三：从密钥库中直接读取证书<br />
&nbsp;&nbsp;&nbsp; String pass="123456";<br />
&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<br />
&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<br />
&nbsp;&nbsp;&nbsp; ks.load(in,pass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; java.security.cert.Certificate c=ks.getCertificate(alias);//alias为条目的别名</span></p>
<p><span style="font-family: Courier New">四：JAVA程序中显示证书指定信息<br />
&nbsp;&nbsp;&nbsp; System.out.println("输出证书信息:\n"+c.toString());<br />
&nbsp;&nbsp;&nbsp; System.out.println("版本号:"+t.getVersion());<br />
&nbsp;&nbsp;&nbsp; System.out.println("序列号:"+t.getSerialNumber().toString(16));<br />
&nbsp;&nbsp;&nbsp; System.out.println("主体名："+t.getSubjectDN());<br />
&nbsp;&nbsp;&nbsp; System.out.println("签发者："+t.getIssuerDN());<br />
&nbsp;&nbsp;&nbsp; System.out.println("有效期："+t.getNotBefore());<br />
&nbsp;&nbsp;&nbsp; System.out.println("签名算法："+t.getSigAlgName());<br />
&nbsp;&nbsp;&nbsp; byte [] sig=t.getSignature();//签名值&nbsp;<br />
&nbsp;&nbsp;&nbsp; PublicKey pk=t.getPublicKey();<br />
&nbsp;&nbsp;&nbsp; byte [] pkenc=pk.getEncoded();&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; System.out.println("公钥");<br />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;pkenc.length;i++)System.out.print(pkenc[i]+",");</span></p>
<p><span style="font-family: Courier New">五：JAVA程序列出密钥库所有条目<br />
&nbsp;&nbsp;&nbsp; String pass="123456";<br />
&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<br />
&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<br />
&nbsp;&nbsp;&nbsp; ks.load(in,pass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; Enumeration e=ks.aliases();<br />
&nbsp;&nbsp;&nbsp; while(e.hasMoreElements())<br />
&nbsp;&nbsp;&nbsp; java.security.cert.Certificate c=ks.getCertificate((String)e.nextElement());</span></p>
<p><span style="font-family: Courier New">六：JAVA程序修改密钥库口令<br />
&nbsp;&nbsp;&nbsp; String oldpass="123456";<br />
&nbsp;&nbsp;&nbsp; String newpass="654321";<br />
&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<br />
&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<br />
&nbsp;&nbsp;&nbsp; ks.load(in,oldpass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; in.close();<br />
&nbsp;&nbsp;&nbsp; FileOutputStream output=new FileOutputStream(".keystore");<br />
&nbsp;&nbsp;&nbsp; ks.store(output,newpass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; output.close();</span></p>
<p><span style="font-family: Courier New">七：JAVA程序修改密钥库条目的口令及添加条目<br />
&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<br />
&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<br />
&nbsp;&nbsp;&nbsp; ks.load(in,storepass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; Certificate [] cchain=ks.getCertificate(alias);获取别名对应条目的证书链<br />
&nbsp;&nbsp;&nbsp; PrivateKey pk=(PrivateKey)ks.getKey(alias,oldkeypass.toCharArray());获取别名对应条目的私钥<br />
&nbsp;&nbsp;&nbsp; ks.setKeyEntry(alias,pk,newkeypass.toCharArray(),cchain);向密钥库中添加条目<br />
&nbsp;&nbsp;&nbsp; 第一个参数指定所添加条目的别名，假如使用已存在别名将覆盖已存在条目，使用新别名将增加一个新条目，第二个参数为条目的私钥，第三个为设置的新口令，第四个为该私钥的公钥的证书链<br />
&nbsp;&nbsp;&nbsp; FileOutputStream output=new FileOutputStream("another");<br />
&nbsp;&nbsp;&nbsp; ks.store(output,storepass.toCharArray())将keystore对象内容写入新文件</span></p>
<p><span style="font-family: Courier New">八：JAVA程序检验别名和删除条目<br />
&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<br />
&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<br />
&nbsp;&nbsp;&nbsp; ks.load(in,storepass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; ks.containsAlias("sage");检验条目是否在密钥库中，存在返回true<br />
&nbsp;&nbsp;&nbsp; ks.deleteEntry("sage");删除别名对应的条目<br />
&nbsp;&nbsp;&nbsp; FileOutputStream output=new FileOutputStream(".keystore");<br />
&nbsp;&nbsp;&nbsp; ks.store(output,storepass.toCharArray())将keystore对象内容写入文件,条目删除成功</span></p>
<p><span style="font-family: Courier New">九：JAVA程序签发数字证书<br />
&nbsp;&nbsp;&nbsp; （1）从密钥库中读取CA的证书<br />
&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<br />
&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<br />
&nbsp;&nbsp;&nbsp; ks.load(in,storepass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; java.security.cert.Certificate c1=ks.getCertificate("caroot");<br />
&nbsp;&nbsp;&nbsp; （2）从密钥库中读取CA的私钥<br />
&nbsp;&nbsp;&nbsp; PrivateKey caprk=(PrivateKey)ks.getKey(alias,cakeypass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; （3）从CA的证书中提取签发者的信息<br />
&nbsp;&nbsp;&nbsp; byte[] encod1=c1.getEncoded();&nbsp;&nbsp;&nbsp; 提取CA证书的编码<br />
&nbsp;&nbsp;&nbsp; X509CertImpl cimp1=new X509CertImpl(encod1);&nbsp; 用该编码创建X509CertImpl类型对象<br />
&nbsp;&nbsp;&nbsp; X509CertInfo cinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);&nbsp; 获取X509CertInfo对象<br />
&nbsp;&nbsp;&nbsp; X500Name issuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME); 获取X509Name类型的签发者信息<br />
&nbsp;&nbsp;&nbsp; （4）获取待签发的证书<br />
&nbsp;&nbsp;&nbsp; CertificateFactory cf=CertificateFactory.getInstance("X.509");<br />
&nbsp;&nbsp;&nbsp; FileInputStream in2=new FileInputStream("user.csr");<br />
&nbsp;&nbsp;&nbsp; java.security.cert.Certificate c2=cf.generateCertificate(in);<br />
&nbsp;&nbsp;&nbsp; （5）从待签发的证书中提取证书信息<br />
&nbsp;&nbsp;&nbsp; byte [] encod2=c2.getEncoded();<br />
&nbsp;&nbsp;&nbsp; X509CertImpl cimp2=new X509CertImpl(encod2);&nbsp; 用该编码创建X509CertImpl类型对象<br />
&nbsp;&nbsp;&nbsp; X509CertInfo cinfo2=(X509CertInfo)cimp2.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);&nbsp; 获取X509CertInfo对象<br />
&nbsp;&nbsp;&nbsp; （6）设置新证书有效期<br />
&nbsp;&nbsp;&nbsp; Date begindate=new Date(); 获取当前时间<br />
&nbsp;&nbsp;&nbsp; Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L); 有效期为3000天<br />
&nbsp;&nbsp;&nbsp; CertificateValidity cv=new CertificateValidity(begindate,enddate); 创建对象<br />
&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.VALIDITY,cv);&nbsp; 设置有效期<br />
&nbsp;&nbsp;&nbsp; （7）设置新证书序列号<br />
&nbsp;&nbsp;&nbsp; int sn=(int)(begindate.getTime()/1000);&nbsp;&nbsp;&nbsp; 以当前时间为序列号<br />
&nbsp;&nbsp;&nbsp; CertificateSerialNumber csn=new CertificateSerialNumber(sn);<br />
&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);<br />
&nbsp;&nbsp;&nbsp; （8）设置新证书签发者<br />
&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);应用第三步的结果<br />
&nbsp;&nbsp;&nbsp; （9）设置新证书签名算法信息<br />
&nbsp;&nbsp;&nbsp; AlgorithmId algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);<br />
&nbsp;&nbsp;&nbsp; cinfo2.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);<br />
&nbsp;&nbsp;&nbsp; （10）创建证书并使用CA的私钥对其签名<br />
&nbsp;&nbsp;&nbsp; X509CertImpl newcert=new X509CertImpl(cinfo2);<br />
&nbsp;&nbsp;&nbsp; newcert.sign(caprk,"MD5WithRSA"); 使用CA私钥对其签名<br />
&nbsp;&nbsp;&nbsp; （11）将新证书写入密钥库<br />
&nbsp;&nbsp;&nbsp; ks.setCertificateEntry("lf_signed",newcert);<br />
&nbsp;&nbsp;&nbsp; FileOutputStream out=new FileOutputStream("newstore");<br />
&nbsp;&nbsp;&nbsp; ks.store(out,"newpass".toCharArray());&nbsp; 这里是写入了新的密钥库，也可以使用第七条来增加条目</span></p>
<p><span style="font-family: Courier New">十：数字证书的检验<br />
&nbsp;&nbsp;&nbsp; （1）验证证书的有效期<br />
&nbsp;（a）获取X509Certificate类型对象<br />
&nbsp;CertificateFactory cf=CertificateFactory.getInstance("X.509");<br />
&nbsp;&nbsp; &nbsp;FileInputStream in1=new FileInputStream("aa.crt");<br />
&nbsp;&nbsp;java.security.cert.Certificate&nbsp; c1=cf.generateCertificate(in1);<br />
&nbsp;X509Certificate t=(X509Certificate)c1;<br />
&nbsp;&nbsp;in2.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （b）获取日期<br />
&nbsp;Date TimeNow=new Date();<br />
&nbsp;（c）检验有效性<br />
&nbsp;try{<br />
&nbsp;&nbsp;&nbsp; t.checkValidity(TimeNow);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("OK");<br />
&nbsp;}catch(CertificateExpiredException e){&nbsp; //过期<br />
&nbsp;&nbsp;&nbsp; System.out.println("Expired");<br />
&nbsp;&nbsp;&nbsp; System.out.println(e.getMessage());<br />
&nbsp;}catch((CertificateNotYetValidException e){ //尚未生效<br />
&nbsp;&nbsp;&nbsp; System.out.println("Too early");<br />
&nbsp;&nbsp;&nbsp; System.out.println(e.getMessage());}<br />
&nbsp;&nbsp;&nbsp;&nbsp; （2）验证证书签名的有效性<br />
&nbsp;（a）获取CA证书<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CertificateFactory cf=CertificateFactory.getInstance("X.509");<br />
&nbsp;&nbsp; &nbsp; FileInputStream in2=new FileInputStream("caroot.crt");<br />
&nbsp;&nbsp; java.security.cert.Certificate&nbsp; cac=cf.generateCertificate(in2);<br />
&nbsp; in2.close();<br />
&nbsp;（c）获取CA的公钥<br />
&nbsp; PublicKey pbk=cac.getPublicKey();<br />
&nbsp;（b）获取待检验的证书（上步已经获取了，就是C1）<br />
&nbsp;（c）检验证书<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean pass=false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c1.verify(pbk);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass=true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch(Exception e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass=false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(e);<br />
&nbsp; }</span></p>
<p><span style="font-family: Courier New"><img border="0" alt="" src="http://www.soudie.net/top_69880_cat_8/down_info.asp?id=50233" width="1" height="1" mce_src="http://www.soudie.net/top_69880_cat_8/down_info.asp?id=50233" />&nbsp;</span></p>
</span></span>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:29 <a href="http://www.blogjava.net/JeromeKwok/articles/311973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用HttpSessionListener统计在线人数 </title><link>http://www.blogjava.net/JeromeKwok/articles/311972.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:28:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311972.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311972.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311972.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311972.html</trackback:ping><description><![CDATA[<p><span style="font-family: Courier New"><span style="font-size: 10pt">&nbsp; </p>
<p><span style="font-family: Courier New">JSP显示在线人数代码&nbsp;<br />
<br />
<br />
/**&nbsp;<br />
*&nbsp;编写以下SessionCounter.java&nbsp;<br />
*&nbsp;并编译为SessiionCounter.class&nbsp;<br />
*&nbsp;然后放到你的网站的classpath的&nbsp;<br />
*&nbsp;SessionCount(自己建立此目录)下面&nbsp;<br />
*/&nbsp;<br />
</span></p>
<div class="codeStyle">
<ol>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">package</span></strong>&nbsp;SessionCount;&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">import</span></strong>&nbsp;javax.servlet.*;&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">import</span></strong>&nbsp;javax.servlet.http.*;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">public</span></strong>&nbsp;<strong><span style="color: #0000ff">class</span></strong>&nbsp;SessionCounter&nbsp;<strong><span style="color: #0000ff">implements</span></strong>&nbsp;</span><a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionListener.java.html" target="_blank" mce_href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionListener.java.html"><span style="font-family: Courier New" class="classLink"><u>HttpSessionListener</u></span></a><span style="font-family: Courier New">&nbsp;{&nbsp; </span></li>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">private</span></strong>&nbsp;<strong><span style="color: #0000ff">static</span></strong>&nbsp;<strong><span style="color: #0000ff">int</span></strong>&nbsp;activeSessions&nbsp;=&nbsp;0;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">public</span></strong>&nbsp;<strong><span style="color: #0000ff">void</span></strong>&nbsp;sessionCreated(</span><a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionEvent.java.html" target="_blank" mce_href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionEvent.java.html"><span style="font-family: Courier New" class="classLink"><u>HttpSessionEvent</u></span></a><span style="font-family: Courier New">&nbsp;se)&nbsp;{&nbsp; </span></li>
    <li><span style="font-family: Courier New">activeSessions++;&nbsp; </span></li>
    <li><span style="font-family: Courier New">}&nbsp; </span></li>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">public</span></strong>&nbsp;<strong><span style="color: #0000ff">void</span></strong>&nbsp;sessionDestroyed(</span><a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionEvent.java.html" target="_blank" mce_href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionEvent.java.html"><span style="font-family: Courier New" class="classLink"><u>HttpSessionEvent</u></span></a><span style="font-family: Courier New">&nbsp;se)&nbsp;{&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">if</span></strong>(activeSessions&nbsp;&gt;&nbsp;0)&nbsp; </span></li>
    <li><span style="font-family: Courier New">activeSessions--;&nbsp; </span></li>
    <li><span style="font-family: Courier New">}&nbsp; </span></li>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">public</span></strong>&nbsp;<strong><span style="color: #0000ff">static</span></strong>&nbsp;<strong><span style="color: #0000ff">int</span></strong>&nbsp;getActiveSessions()&nbsp;{&nbsp; </span></li>
    <li><span style="font-family: Courier New"><strong><span style="color: #0000ff">return</span></strong>&nbsp;activeSessions;&nbsp; </span></li>
    <li><span style="font-family: Courier New">}&nbsp; </span></li>
    <li><span style="font-family: Courier New">}&nbsp; </span></li>
</ol>
</div>
<p><br />
<span style="font-family: Courier New">接着建立online.jsp文件用于显示在线人数&nbsp;<br />
&lt;%@&nbsp;page&nbsp;import="SessionCount.SessionCounter"&nbsp;%&gt;&nbsp;<br />
在线：&lt;%=&nbsp;SessionCounter.getActiveSessions()&nbsp;%&gt;&nbsp;<br />
<br />
然后需要在你的网站的WEB-INF中建立web.xml&nbsp;<br />
文件内容如下：&nbsp;<br />
</span></p>
<div class="codeStyle">
<ol>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;!--&nbsp;Web.xml&nbsp;--&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;?xml&nbsp;version=<span style="color: #ff33ff">"1.0"</span>&nbsp;encoding=<span style="color: #ff33ff">"ISO-8859-1"</span>?&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;!DOCTYPE&nbsp;web-app&nbsp; </span></li>
    <li><span style="font-family: Courier New">PUBLIC&nbsp;<span style="color: #ff33ff">"-//Sun&nbsp;Microsystems,&nbsp;Inc.//DTD&nbsp;Web&nbsp;Application&nbsp;2.3//EN"</span>&nbsp; </span></li>
    <li><span style="font-family: Courier New"><span style="color: #ff33ff">"http://java.sun.com/j2ee/dtds/web-app_2.3.dtd"</span>&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;web-app&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;!--&nbsp;Listeners&nbsp;--&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;listener&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;listener-<strong><span style="color: #0000ff">class</span></strong>&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">SessionCount.SessionCounter&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;/listener-<strong><span style="color: #0000ff">class</span></strong>&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;/listener&gt;&nbsp; </span></li>
    <li><span style="font-family: Courier New">&nbsp; </span></li>
    <li><span style="font-family: Courier New">&lt;/web-app&gt;&nbsp; </span></li>
</ol>
</div>
</span></span>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:28 <a href="http://www.blogjava.net/JeromeKwok/articles/311972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 范型攻略篇</title><link>http://www.blogjava.net/JeromeKwok/articles/311970.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:26:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311970.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311970.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311970.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311970.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311970.html</trackback:ping><description><![CDATA[<p style="font-family: Comic Sans MS; font-size: 10pt"><span style="font-family: Courier New">在已发布的Java1.4中在核心代码库中增加了许多新的API(如Loging,正则表达式，NIO)等，在最新发布的JDK1.5和即将发布的JDK1.6中也新增了许多API，其中比较有重大意义的就是Generics(范型）。<br />
<br />
一.什么是Generics?<br />
<br />
Generics可以称之为参数类型(parameterized&nbsp;types),由编译器来验证从客户端将一种类型传送给某一对象的机制。如Java.util.ArrayList,<br />
<br />
编译器可以用Generics来保证类型安全。<br />
在我们深入了解Generics之前,我们先来看一看当前的java&nbsp;集合框架（Collection)。在j2SE1.4中所有集合的Root&nbsp;Interface是Collection<br />
<br />
Collections&nbsp;example&nbsp;without&nbsp;genericity:&nbsp;Example&nbsp;1<br />
<br />
1&nbsp;protected&nbsp;void&nbsp;collectionsExample()&nbsp;{<br />
2&nbsp;&nbsp;ArrayList&nbsp;list&nbsp;=&nbsp;new&nbsp;ArrayList();<br />
3&nbsp;&nbsp;list.add(new&nbsp;String("test&nbsp;string"));<br />
4&nbsp;&nbsp;list.add(new&nbsp;Integer(9));&nbsp;//&nbsp;purposely&nbsp;placed&nbsp;here&nbsp;to&nbsp;create&nbsp;a&nbsp;runtime&nbsp;ClassCastException<br />
5&nbsp;&nbsp;inspectCollection(list);<br />
6&nbsp;}<br />
7<br />
8<br />
9&nbsp;protected&nbsp;void&nbsp;inspectCollection(Collection&nbsp;aCollection)&nbsp;{<br />
10&nbsp;&nbsp;Iterator&nbsp;i&nbsp;=&nbsp;aCollection.iterator();<br />
11&nbsp;&nbsp;while&nbsp;(i.hasNext())&nbsp;{<br />
12&nbsp;&nbsp;&nbsp;String&nbsp;element&nbsp;=&nbsp;(String)&nbsp;i.next();<br />
13&nbsp;&nbsp;}<br />
14&nbsp;}<br />
<br />
<br />
以上的样例程序包含的两个方法，collectionExample方法建立了一个简单的集合类型ArrayList，并在ArrayList中增加了一个String和一个Integer对象.而在inspecCollection方法中，我们迭代这个ArrayList用String进行Cast。我们看第二个方法，就出现了一个问题,Collection在内部用的是Object，而我们要取出Collection中的对象时,需要进行Cast，那么开发者必需用实际的类型进行Cast,像这种向下造型，编译器无<br />
<br />
法进行检查,如此一来我们就要冒在代码在运行抛出ClassCastException的危险。我们看inspecCollection方法，编译时没有问题，但在运行时就会抛出ClassCastException异常。所以我们一定要远离这个重大的运行时错误<br />
<br />
<br />
二.使用Generics<br />
从上一章节中的CassCastException这种异常，我们期望在代码编译时就能够捕捉到,下面我们使用范型修改上一章的样例程序。<br />
//Example&nbsp;2<br />
1&nbsp;protected&nbsp;void&nbsp;collectionsExample()&nbsp;{<br />
2&nbsp;&nbsp;ArrayList&lt;String&gt;&nbsp;list&nbsp;=&nbsp;new&nbsp;ArrayList&lt;String&gt;();<br />
3&nbsp;&nbsp;list.add(new&nbsp;String("test&nbsp;string"));<br />
4&nbsp;&nbsp;//&nbsp;list.add(new&nbsp;Integer(9));&nbsp;this&nbsp;no&nbsp;longer&nbsp;compiles<br />
5&nbsp;&nbsp;inspectCollection(list);<br />
6&nbsp;}<br />
7&nbsp;<br />
8&nbsp;<br />
9&nbsp;protected&nbsp;void&nbsp;inspectCollection(Collection&lt;String&gt;&nbsp;aCollection)&nbsp;{<br />
10&nbsp;&nbsp;Iterator&lt;String&gt;&nbsp;i&nbsp;=&nbsp;aCollection.iterator();<br />
11&nbsp;&nbsp;while(i.hasNext())&nbsp;{<br />
12&nbsp;&nbsp;&nbsp;String&nbsp;element&nbsp;=&nbsp;i.next();<br />
13&nbsp;&nbsp;}<br />
14&nbsp;}<br />
<br />
<br />
从上面第2行我们在创建ArrayList时使用了新语法，在JDK1.5中所有的Collection都加入了Generics的声明。例:<br />
//Example&nbsp;3<br />
1&nbsp;public&nbsp;class&nbsp;ArrayList&lt;E&gt;&nbsp;extends&nbsp;AbstractList&lt;E&gt;&nbsp;{<br />
2&nbsp;&nbsp;//&nbsp;details&nbsp;omitted...<br />
3&nbsp;&nbsp;public&nbsp;void&nbsp;add(E&nbsp;element)&nbsp;{<br />
4&nbsp;&nbsp;&nbsp;//&nbsp;details&nbsp;omitted<br />
5&nbsp;&nbsp;}<br />
6&nbsp;&nbsp;public&nbsp;Iterator&lt;E&gt;&nbsp;iterator()&nbsp;{<br />
7&nbsp;&nbsp;&nbsp;//&nbsp;details&nbsp;omitted<br />
8&nbsp;&nbsp;}<br />
9&nbsp;}<br />
<br />
<br />
这个E是一个类型变量，并没有对它进行具体类型的定义,它只是在定义ArrayList时的类型占位符,在Example&nbsp;2中的我们在定义ArrayList的实<br />
<br />
例时用String绑定在E上,当我们用add(E&nbsp;element)方法向ArrayList中增加对象时,&nbsp;那么就像下面的写法一样：&nbsp;public&nbsp;void&nbsp;add(String&nbsp;element)；因为在ArrayList所有方法都会用String来替代E,无论是方法的参数还是返回值。这时我们在看Example&nbsp;2中的第四行，编译就会反映出编译错误。<br />
所以在java中增加Generics主要的目的是为了增加类型安全。<br />
<br />
通过上面的简单的例子我们看到使用Generics的好处有：<br />
1.在类型没有变化时，Collection是类型安全的。<br />
2.内在的类型转换优于在外部的人工造型。<br />
3.使Java&nbsp;接口更加强壮,因为它增加了类型。<br />
4.类型的匹配错误在编译阶段就可以捕捉到，而不是在代码运行时。<br />
<br />
受约束类型变量<br />
虽然许多Class被设计成Generics，但类型变量可以是受限的<br />
public&nbsp;class&nbsp;C1&lt;T&nbsp;extends&nbsp;Number&gt;&nbsp;{&nbsp;}<br />
public&nbsp;class&nbsp;C2&lt;T&nbsp;extends&nbsp;Person&nbsp;&amp;&nbsp;Comparable&gt;&nbsp;{&nbsp;}&nbsp;<br />
第一个T变量必须继承Number，第二个T必须继承Person和实现Comparable<br />
<br />
三.Generics&nbsp;方法<br />
<br />
像Generics类一样，方法和构造函数也可以有类型参数。方法的参数的返回值都可以有类型参数，进行Generics。<br />
//Example&nbsp;4<br />
1&nbsp;public&nbsp;&lt;T&nbsp;extends&nbsp;Comparable&gt;&nbsp;T&nbsp;max(T&nbsp;t1,&nbsp;T&nbsp;t2)&nbsp;{<br />
2&nbsp;&nbsp;if&nbsp;(t1.compareTo(t2)&nbsp;&gt;&nbsp;0)<br />
3&nbsp;&nbsp;&nbsp;return&nbsp;t1;<br />
4&nbsp;&nbsp;else&nbsp;return&nbsp;t2;<br />
5&nbsp;}<br />
<br />
<br />
这里，max方法的参数类型为单一的T类型，而T类型继承了Comparable，max的参数和返回值都有相同的超类。下面的Example&nbsp;5显示了max方法的几个约束。<br />
//Example&nbsp;5　<br />
1&nbsp;Integer&nbsp;iresult&nbsp;=&nbsp;max(new&nbsp;Integer(100),&nbsp;new&nbsp;Integer(200));<br />
2&nbsp;String&nbsp;sresult&nbsp;=&nbsp;max("AA",&nbsp;"BB");<br />
3&nbsp;Number&nbsp;nresult&nbsp;=&nbsp;max(new&nbsp;Integer(100),&nbsp;"AAA");&nbsp;//&nbsp;does&nbsp;not&nbsp;compile<br />
<br />
<br />
在Example&nbsp;5第1行参数都为Integer，所以返回值也是Integer，注意返回值没有进行造型。<br />
在Example&nbsp;5第2行参数都为String，所以返回值也是String，注意返回值没有进行造型。以上都调用了同一个方法。<br />
在Example&nbsp;5第3行产生以下编译错误：<br />
Example.java:10:&nbsp;incompatible&nbsp;types<br />
found&nbsp;&nbsp;:&nbsp;java.lang.Object&amp;java.io.Serializable&amp;java.lang.Comparable&lt;?&gt;<br />
required:&nbsp;java.lang.Number<br />
&nbsp;&nbsp;&nbsp;&nbsp;Number&nbsp;nresult&nbsp;=&nbsp;max(new&nbsp;Integer(100),&nbsp;"AAA");<br />
<br />
这个错误发生是因为编译器无法确定返回值类型，因为String和Integer都有相同的超类Object,注意就算我们修正了第三行，这行代码在运行仍然会报错，因为比较了不同的对象。<br />
<br />
四.向下兼容<br />
任何一个新的特色在新的JDK版本中出来后，我们首先关心的是如何于以前编写的代码兼容。也就是说我们编写的Example&nbsp;1程序不需要任何的改变就可以运行,但是编译器会给出一个"ROW&nbsp;TYPE"的警告。在JDK1.4中编写的代码如何在JVM1.5中完全兼容运行,我们要人工进行一个:Type&nbsp;erasure处理过程<br />
<br />
五.通配符<br />
<br />
//Example&nbsp;6<br />
List&lt;String&gt;&nbsp;stringList&nbsp;=&nbsp;new&nbsp;ArrayList&lt;String&gt;();&nbsp;//1<br />
List&lt;Object&gt;&nbsp;objectList&nbsp;=&nbsp;stringList&nbsp;;//2<br />
objectList&nbsp;.add(new&nbsp;Object());&nbsp;//&nbsp;3<br />
String&nbsp;s&nbsp;=&nbsp;stringList&nbsp;.get(0);//4<br />
<br />
<br />
乍一看，Example&nbsp;<br />
<br />
6是正确的。但stringList本意是存放String类型的ArrayList,而objectList中可以存入任何对象，当在第3行进行处理时，stringList也就无法保证是String类型的ArrayList,此时编译器不允许这样的事出现，所以第3行将无法编译。<br />
<br />
//Example&nbsp;7<br />
void&nbsp;printCollection(Collection&lt;Object&gt;&nbsp;c)&nbsp;<br />
{&nbsp;for&nbsp;(Object&nbsp;e&nbsp;:&nbsp;c)&nbsp;{&nbsp;<br />
System.out.println(e);<br />
}}<br />
<br />
<br />
Example&nbsp;7的本意是打印所有Collection的对象,但是正如Example&nbsp;6所说的，编译会报错，此时就可以用通配符&#8220;？&#8221;来修改Example&nbsp;7<br />
<br />
//Example&nbsp;8<br />
void&nbsp;printCollection(Collection&lt;?&gt;&nbsp;c)&nbsp;<br />
{&nbsp;for&nbsp;(Object&nbsp;e&nbsp;:&nbsp;c)&nbsp;{&nbsp;<br />
System.out.println(e);<br />
}}<br />
<br />
<br />
Example&nbsp;8中所有Collection类型就可以方便的打印了<br />
<br />
有界通配符&nbsp;&lt;T&nbsp;extends&nbsp;Number&gt;(上界)&nbsp;&lt;T&nbsp;super&nbsp;Number&gt;(下界)&nbsp;<br />
<br />
六.创建自己的范型<br />
以下代码来自</span><a href="http://www.java2s.com/ExampleCode/Language-Basics" mce_href="http://www.java2s.com/ExampleCode/Language-Basics"><span style="font-family: Courier New">http://www.java2s.com/ExampleCode/Language-Basics</span></a><br />
<span style="font-family: Courier New">1.一个参数的Generics<br />
//Example&nbsp;9(没有使用范型)<br />
class&nbsp;NonGen&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;Object&nbsp;ob;&nbsp;//&nbsp;ob&nbsp;is&nbsp;now&nbsp;of&nbsp;type&nbsp;Object&nbsp;<br />
&nbsp;&nbsp;//&nbsp;Pass&nbsp;the&nbsp;constructor&nbsp;a&nbsp;reference&nbsp;to&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;//&nbsp;an&nbsp;object&nbsp;of&nbsp;type&nbsp;Object&nbsp;<br />
&nbsp;&nbsp;NonGen(Object&nbsp;o)&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ob&nbsp;=&nbsp;o;&nbsp;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;&nbsp;//&nbsp;Return&nbsp;type&nbsp;Object.&nbsp;<br />
&nbsp;&nbsp;Object&nbsp;getob()&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ob;&nbsp;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;&nbsp;//&nbsp;Show&nbsp;type&nbsp;of&nbsp;ob.&nbsp;&nbsp;<br />
&nbsp;&nbsp;void&nbsp;showType()&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Type&nbsp;of&nbsp;ob&nbsp;is&nbsp;"&nbsp;+&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ob.getClass().getName());&nbsp;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;<br />
}&nbsp;&nbsp;<br />
//&nbsp;Demonstrate&nbsp;the&nbsp;non-generic&nbsp;class.&nbsp;&nbsp;<br />
public&nbsp;class&nbsp;NonGenDemo&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;args[])&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;NonGen&nbsp;iOb;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Create&nbsp;NonGen&nbsp;Object&nbsp;and&nbsp;store&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;an&nbsp;Integer&nbsp;in&nbsp;it.&nbsp;Autoboxing&nbsp;still&nbsp;occurs.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;iOb&nbsp;=&nbsp;new&nbsp;NonGen(88);&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Show&nbsp;the&nbsp;type&nbsp;of&nbsp;data&nbsp;used&nbsp;by&nbsp;iOb.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;iOb.showType();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Get&nbsp;the&nbsp;value&nbsp;of&nbsp;iOb.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;This&nbsp;time,&nbsp;a&nbsp;cast&nbsp;is&nbsp;necessary.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;v&nbsp;=&nbsp;(Integer)&nbsp;iOb.getob();&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("value:&nbsp;"&nbsp;+&nbsp;v);&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println();&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Create&nbsp;another&nbsp;NonGen&nbsp;object&nbsp;and&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;store&nbsp;a&nbsp;String&nbsp;in&nbsp;it.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;NonGen&nbsp;strOb&nbsp;=&nbsp;new&nbsp;NonGen("Non-Generics&nbsp;Test");&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Show&nbsp;the&nbsp;type&nbsp;of&nbsp;data&nbsp;used&nbsp;by&nbsp;strOb.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;strOb.showType();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Get&nbsp;the&nbsp;value&nbsp;of&nbsp;strOb.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Again,&nbsp;notice&nbsp;that&nbsp;a&nbsp;cast&nbsp;is&nbsp;necessary.&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;str&nbsp;=&nbsp;(String)&nbsp;strOb.getob();&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("value:&nbsp;"&nbsp;+&nbsp;str);&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;This&nbsp;compiles,&nbsp;but&nbsp;is&nbsp;conceptually&nbsp;wrong!&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;iOb&nbsp;=&nbsp;strOb;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;v&nbsp;=&nbsp;(Integer)&nbsp;iOb.getob();&nbsp;//&nbsp;runtime&nbsp;error!&nbsp;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;<br />
}<br />
&nbsp;&nbsp;<br />
<br />
//Example&nbsp;10(使用范型)<br />
class&nbsp;Example1&lt;T&gt;{<br />
&nbsp;private&nbsp;T&nbsp;t;<br />
&nbsp;Example1(T&nbsp;o){<br />
&nbsp;&nbsp;this.t=o;<br />
&nbsp;&nbsp;}<br />
&nbsp;T&nbsp;getOb(){<br />
&nbsp;&nbsp;return&nbsp;t;<br />
&nbsp;}<br />
&nbsp;void&nbsp;ShowObject(){<br />
&nbsp;&nbsp;System.out.println("对象的类型是："+t.getClass().getName());<br />
&nbsp;}<br />
}<br />
public&nbsp;class&nbsp;GenericsExample1&nbsp;{<br />
<br />
&nbsp;/**<br />
&nbsp;&nbsp;*&nbsp;@param&nbsp;args<br />
&nbsp;&nbsp;*/<br />
&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub<br />
&nbsp;&nbsp;Example1&lt;Integer&gt;&nbsp;examplei=new&nbsp;Example1&lt;Integer&gt;(100);<br />
&nbsp;&nbsp;examplei.ShowObject();<br />
&nbsp;&nbsp;System.out.println("对象是："+examplei.getOb());<br />
&nbsp;&nbsp;Example1&lt;String&gt;&nbsp;examples=new&nbsp;Example1&lt;String&gt;("Bill");<br />
&nbsp;&nbsp;examples.ShowObject();<br />
&nbsp;&nbsp;System.out.println("对象是："+examples.getOb());<br />
&nbsp;}<br />
<br />
}<br />
<br />
<br />
我们来看Example&nbsp;9没有使用范型，所以我们需要进行造型，而Example&nbsp;10我们不需要任何的造型<br />
<br />
2.二个参数的Generics<br />
<br />
//Example&nbsp;11<br />
class&nbsp;TwoGen&lt;T,&nbsp;V&gt;&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;T&nbsp;ob1;&nbsp;<br />
&nbsp;&nbsp;&nbsp;V&nbsp;ob2;&nbsp;<br />
&nbsp;&nbsp;&nbsp;//&nbsp;Pass&nbsp;the&nbsp;constructor&nbsp;a&nbsp;reference&nbsp;to&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;//&nbsp;an&nbsp;object&nbsp;of&nbsp;type&nbsp;T.&nbsp;<br />
&nbsp;&nbsp;&nbsp;TwoGen(T&nbsp;o1,&nbsp;V&nbsp;o2)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ob1&nbsp;=&nbsp;o1;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ob2&nbsp;=&nbsp;o2;&nbsp;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;//&nbsp;Show&nbsp;types&nbsp;of&nbsp;T&nbsp;and&nbsp;V.&nbsp;<br />
&nbsp;&nbsp;&nbsp;void&nbsp;showTypes()&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Type&nbsp;of&nbsp;T&nbsp;is&nbsp;"&nbsp;+&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ob1.getClass().getName());&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Type&nbsp;of&nbsp;V&nbsp;is&nbsp;"&nbsp;+&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ob2.getClass().getName());&nbsp;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;T&nbsp;getob1()&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ob1;&nbsp;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;V&nbsp;getob2()&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ob2;&nbsp;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;}&nbsp;<br />
<br />
public&nbsp;class&nbsp;GenericsExampleByTwoParam&nbsp;{<br />
<br />
&nbsp;/**<br />
&nbsp;&nbsp;*&nbsp;@param&nbsp;args<br />
&nbsp;&nbsp;*/<br />
&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub<br />
&nbsp;&nbsp;TwoGen&lt;Integer,&nbsp;String&gt;&nbsp;tgObj&nbsp;=&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;TwoGen&lt;Integer,&nbsp;String&gt;(88,&nbsp;"Generics");&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Show&nbsp;the&nbsp;types.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tgObj.showTypes();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Obtain&nbsp;and&nbsp;show&nbsp;values.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;v&nbsp;=&nbsp;tgObj.getob1();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("value:&nbsp;"&nbsp;+&nbsp;v);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;str&nbsp;=&nbsp;tgObj.getob2();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("value:&nbsp;"&nbsp;+&nbsp;str);&nbsp;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;<br />
<br />
&nbsp;}<br />
<br />
<br />
3.Generics的Hierarchy<br />
<br />
//Example&nbsp;12<br />
class&nbsp;Stats&lt;T&nbsp;extends&nbsp;Number&gt;&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;T[]&nbsp;nums;&nbsp;//&nbsp;array&nbsp;of&nbsp;Number&nbsp;or&nbsp;subclass&nbsp;<br />
&nbsp;&nbsp;&nbsp;//&nbsp;Pass&nbsp;the&nbsp;constructor&nbsp;a&nbsp;reference&nbsp;to&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;//&nbsp;an&nbsp;array&nbsp;of&nbsp;type&nbsp;Number&nbsp;or&nbsp;subclass.&nbsp;<br />
&nbsp;&nbsp;&nbsp;Stats(T[]&nbsp;o)&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nums&nbsp;=&nbsp;o;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;//&nbsp;Return&nbsp;type&nbsp;double&nbsp;in&nbsp;all&nbsp;cases.&nbsp;<br />
&nbsp;&nbsp;&nbsp;double&nbsp;average()&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double&nbsp;sum&nbsp;=&nbsp;0.0;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=0;&nbsp;i&nbsp;&lt;&nbsp;nums.length;&nbsp;i++)&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;+=&nbsp;nums[i].doubleValue();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;sum&nbsp;/&nbsp;nums.length;&nbsp;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;}&nbsp;&nbsp;<br />
public&nbsp;class&nbsp;GenericsExampleByHierarchy&nbsp;{<br />
&nbsp;<br />
<br />
&nbsp;/**<br />
&nbsp;&nbsp;*&nbsp;@param&nbsp;args<br />
&nbsp;&nbsp;*/<br />
&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub<br />
<br />
&nbsp;&nbsp;&nbsp;Integer&nbsp;inums[]&nbsp;=&nbsp;{&nbsp;1,&nbsp;2,&nbsp;3,&nbsp;4,&nbsp;5&nbsp;};&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stats&lt;Integer&gt;&nbsp;iob&nbsp;=&nbsp;new&nbsp;Stats&lt;Integer&gt;(inums);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double&nbsp;v&nbsp;=&nbsp;iob.average();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("iob&nbsp;average&nbsp;is&nbsp;"&nbsp;+&nbsp;v);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Double&nbsp;dnums[]&nbsp;=&nbsp;{&nbsp;1.1,&nbsp;2.2,&nbsp;3.3,&nbsp;4.4,&nbsp;5.5&nbsp;};&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stats&lt;Double&gt;&nbsp;dob&nbsp;=&nbsp;new&nbsp;Stats&lt;Double&gt;(dnums);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double&nbsp;w&nbsp;=&nbsp;dob.average();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("dob&nbsp;average&nbsp;is&nbsp;"&nbsp;+&nbsp;w);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;This&nbsp;won't&nbsp;compile&nbsp;because&nbsp;String&nbsp;is&nbsp;not&nbsp;a&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;subclass&nbsp;of&nbsp;Number.&nbsp;<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;strs[]&nbsp;=&nbsp;{&nbsp;"1",&nbsp;"2",&nbsp;"3",&nbsp;"4",&nbsp;"5"&nbsp;};&nbsp;<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stats&lt;String&gt;&nbsp;strob&nbsp;=&nbsp;new&nbsp;Stats&lt;String&gt;(strs);&nbsp;&nbsp;&nbsp;<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double&nbsp;x&nbsp;=&nbsp;strob.average();&nbsp;<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("strob&nbsp;average&nbsp;is&nbsp;"&nbsp;+&nbsp;v);&nbsp;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;}<br />
&nbsp;&nbsp;<br />
<br />
4.使用通配符<br />
//Example&nbsp;14<br />
class&nbsp;StatsWildCard&lt;T&nbsp;extends&nbsp;Number&gt;&nbsp;{<br />
&nbsp;T[]&nbsp;nums;&nbsp;//&nbsp;array&nbsp;of&nbsp;Number&nbsp;or&nbsp;subclass<br />
&nbsp;//&nbsp;Pass&nbsp;the&nbsp;constructor&nbsp;a&nbsp;reference&nbsp;to<br />
&nbsp;//&nbsp;an&nbsp;array&nbsp;of&nbsp;type&nbsp;Number&nbsp;or&nbsp;subclass.<br />
&nbsp;StatsWildCard(T[]&nbsp;o)&nbsp;{<br />
&nbsp;&nbsp;nums&nbsp;=&nbsp;o;<br />
&nbsp;}<br />
&nbsp;//&nbsp;Return&nbsp;type&nbsp;double&nbsp;in&nbsp;all&nbsp;cases.<br />
&nbsp;double&nbsp;average()&nbsp;{<br />
&nbsp;&nbsp;double&nbsp;sum&nbsp;=&nbsp;0.0;<br />
&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;nums.length;&nbsp;i++)<br />
&nbsp;&nbsp;&nbsp;sum&nbsp;+=&nbsp;nums[i].doubleValue();<br />
&nbsp;&nbsp;return&nbsp;sum&nbsp;/&nbsp;nums.length;<br />
&nbsp;}<br />
&nbsp;//&nbsp;Determine&nbsp;if&nbsp;two&nbsp;averages&nbsp;are&nbsp;the&nbsp;same.<br />
&nbsp;//&nbsp;Notice&nbsp;the&nbsp;use&nbsp;of&nbsp;the&nbsp;wildcard.<br />
&nbsp;boolean&nbsp;sameAvg(StatsWildCard&lt;?&gt;&nbsp;ob)&nbsp;{<br />
&nbsp;&nbsp;if&nbsp;(average()&nbsp;==&nbsp;ob.average())<br />
&nbsp;&nbsp;&nbsp;return&nbsp;true;<br />
&nbsp;&nbsp;return&nbsp;false;<br />
&nbsp;}<br />
}<br />
<br />
public&nbsp;class&nbsp;GenericsExampleByWildcard&nbsp;{<br />
<br />
&nbsp;/**<br />
&nbsp;&nbsp;*&nbsp;@param&nbsp;args<br />
&nbsp;&nbsp;*/<br />
&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub<br />
&nbsp;&nbsp;Integer&nbsp;inums[]&nbsp;=&nbsp;{&nbsp;1,&nbsp;2,&nbsp;3,&nbsp;4,&nbsp;5&nbsp;};<br />
&nbsp;&nbsp;StatsWildCard&lt;Integer&gt;&nbsp;iob&nbsp;=&nbsp;new&nbsp;StatsWildCard&lt;Integer&gt;(inums);<br />
&nbsp;&nbsp;double&nbsp;v&nbsp;=&nbsp;iob.average();<br />
&nbsp;&nbsp;System.out.println("iob&nbsp;average&nbsp;is&nbsp;"&nbsp;+&nbsp;v);<br />
&nbsp;&nbsp;Double&nbsp;dnums[]&nbsp;=&nbsp;{&nbsp;1.1,&nbsp;2.2,&nbsp;3.3,&nbsp;4.4,&nbsp;5.5&nbsp;};<br />
&nbsp;&nbsp;StatsWildCard&lt;Double&gt;&nbsp;dob&nbsp;=&nbsp;new&nbsp;StatsWildCard&lt;Double&gt;(dnums);<br />
&nbsp;&nbsp;double&nbsp;w&nbsp;=&nbsp;dob.average();<br />
&nbsp;&nbsp;System.out.println("dob&nbsp;average&nbsp;is&nbsp;"&nbsp;+&nbsp;w);<br />
&nbsp;&nbsp;Float&nbsp;fnums[]&nbsp;=&nbsp;{&nbsp;1.0F,&nbsp;2.0F,&nbsp;3.0F,&nbsp;4.0F,&nbsp;5.0F&nbsp;};<br />
&nbsp;&nbsp;StatsWildCard&lt;Float&gt;&nbsp;fob&nbsp;=&nbsp;new&nbsp;StatsWildCard&lt;Float&gt;(fnums);<br />
&nbsp;&nbsp;double&nbsp;x&nbsp;=&nbsp;fob.average();<br />
&nbsp;&nbsp;System.out.println("fob&nbsp;average&nbsp;is&nbsp;"&nbsp;+&nbsp;x);<br />
&nbsp;&nbsp;//&nbsp;See&nbsp;which&nbsp;arrays&nbsp;have&nbsp;same&nbsp;average.<br />
&nbsp;&nbsp;System.out.print("Averages&nbsp;of&nbsp;iob&nbsp;and&nbsp;dob&nbsp;");<br />
&nbsp;&nbsp;if&nbsp;(iob.sameAvg(dob))<br />
&nbsp;&nbsp;&nbsp;System.out.println("are&nbsp;the&nbsp;same.");<br />
&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;System.out.println("differ.");<br />
&nbsp;&nbsp;System.out.print("Averages&nbsp;of&nbsp;iob&nbsp;and&nbsp;fob&nbsp;");<br />
&nbsp;&nbsp;if&nbsp;(iob.sameAvg(fob))<br />
&nbsp;&nbsp;&nbsp;System.out.println("are&nbsp;the&nbsp;same.");<br />
&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;System.out.println("differ.");<br />
<br />
&nbsp;}<br />
<br />
}<br />
<br />
<br />
5.使用边界通配符<br />
//Example&nbsp;15<br />
class&nbsp;TwoD&nbsp;{&nbsp;<br />
&nbsp;&nbsp;int&nbsp;x,&nbsp;y;&nbsp;<br />
&nbsp;&nbsp;TwoD(int&nbsp;a,&nbsp;int&nbsp;b)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;=&nbsp;a;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;y&nbsp;=&nbsp;b;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
}&nbsp;<br />
//&nbsp;Three-dimensional&nbsp;coordinates.&nbsp;<br />
class&nbsp;ThreeD&nbsp;extends&nbsp;TwoD&nbsp;{&nbsp;<br />
&nbsp;&nbsp;int&nbsp;z;&nbsp;<br />
&nbsp;&nbsp;ThreeD(int&nbsp;a,&nbsp;int&nbsp;b,&nbsp;int&nbsp;c)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;super(a,&nbsp;b);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;z&nbsp;=&nbsp;c;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
}&nbsp;<br />
//&nbsp;Four-dimensional&nbsp;coordinates.&nbsp;<br />
class&nbsp;FourD&nbsp;extends&nbsp;ThreeD&nbsp;{&nbsp;<br />
&nbsp;&nbsp;int&nbsp;t;&nbsp;<br />
&nbsp;&nbsp;FourD(int&nbsp;a,&nbsp;int&nbsp;b,&nbsp;int&nbsp;c,&nbsp;int&nbsp;d)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;super(a,&nbsp;b,&nbsp;c);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;=&nbsp;d;&nbsp;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
}&nbsp;<br />
//&nbsp;This&nbsp;class&nbsp;holds&nbsp;an&nbsp;array&nbsp;of&nbsp;coordinate&nbsp;objects.&nbsp;<br />
class&nbsp;Coords&lt;T&nbsp;extends&nbsp;TwoD&gt;&nbsp;{&nbsp;<br />
&nbsp;&nbsp;T[]&nbsp;coords;&nbsp;<br />
&nbsp;&nbsp;Coords(T[]&nbsp;o)&nbsp;{&nbsp;coords&nbsp;=&nbsp;o;&nbsp;}&nbsp;<br />
}&nbsp;<br />
//&nbsp;Demonstrate&nbsp;a&nbsp;bounded&nbsp;wildcard.&nbsp;<br />
public&nbsp;class&nbsp;BoundedWildcard&nbsp;{&nbsp;<br />
&nbsp;&nbsp;static&nbsp;void&nbsp;showXY(Coords&lt;?&gt;&nbsp;c)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("X&nbsp;Y&nbsp;Coordinates:");&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=0;&nbsp;i&nbsp;&lt;&nbsp;c.coords.length;&nbsp;i++)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(c.coords[i].x&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.coords[i].y);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println();&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;static&nbsp;void&nbsp;showXYZ(Coords&lt;?&nbsp;extends&nbsp;ThreeD&gt;&nbsp;c)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("X&nbsp;Y&nbsp;Z&nbsp;Coordinates:");&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=0;&nbsp;i&nbsp;&lt;&nbsp;c.coords.length;&nbsp;i++)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(c.coords[i].x&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.coords[i].y&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.coords[i].z);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println();&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;static&nbsp;void&nbsp;showAll(Coords&lt;?&nbsp;extends&nbsp;FourD&gt;&nbsp;c)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("X&nbsp;Y&nbsp;Z&nbsp;T&nbsp;Coordinates:");&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=0;&nbsp;i&nbsp;&lt;&nbsp;c.coords.length;&nbsp;i++)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(c.coords[i].x&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.coords[i].y&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.coords[i].z&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.coords[i].t);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println();&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;args[])&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;TwoD&nbsp;td[]&nbsp;=&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;TwoD(0,&nbsp;0),&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;TwoD(7,&nbsp;9),&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;TwoD(18,&nbsp;4),&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;TwoD(-1,&nbsp;-23)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Coords&lt;TwoD&gt;&nbsp;tdlocs&nbsp;=&nbsp;new&nbsp;Coords&lt;TwoD&gt;(td);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Contents&nbsp;of&nbsp;tdlocs.");&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;showXY(tdlocs);&nbsp;//&nbsp;OK,&nbsp;is&nbsp;a&nbsp;TwoD&nbsp;<br />
//&nbsp;&nbsp;showXYZ(tdlocs);&nbsp;//&nbsp;Error,&nbsp;not&nbsp;a&nbsp;ThreeD&nbsp;<br />
//&nbsp;&nbsp;showAll(tdlocs);&nbsp;//&nbsp;Erorr,&nbsp;not&nbsp;a&nbsp;FourD&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Now,&nbsp;create&nbsp;some&nbsp;FourD&nbsp;objects.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;FourD&nbsp;fd[]&nbsp;=&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;FourD(1,&nbsp;2,&nbsp;3,&nbsp;4),&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;FourD(6,&nbsp;8,&nbsp;14,&nbsp;8),&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;FourD(22,&nbsp;9,&nbsp;4,&nbsp;9),&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;FourD(3,&nbsp;-2,&nbsp;-23,&nbsp;17)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Coords&lt;FourD&gt;&nbsp;fdlocs&nbsp;=&nbsp;new&nbsp;Coords&lt;FourD&gt;(fd);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Contents&nbsp;of&nbsp;fdlocs.");&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;These&nbsp;are&nbsp;all&nbsp;OK.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;showXY(fdlocs);&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;showXYZ(fdlocs);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;showAll(fdlocs);&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
6.ArrayList的Generics<br />
//Example&nbsp;16<br />
public&nbsp;class&nbsp;ArrayListGenericDemo&nbsp;{<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;ArrayList&lt;String&gt;&nbsp;data&nbsp;=&nbsp;new&nbsp;ArrayList&lt;String&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;data.add("hello");<br />
&nbsp;&nbsp;&nbsp;&nbsp;data.add("goodbye");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;data.add(new&nbsp;Date());&nbsp;This&nbsp;won't&nbsp;compile!<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Iterator&lt;String&gt;&nbsp;it&nbsp;=&nbsp;data.iterator();<br />
&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(it.hasNext())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
}&nbsp;<br />
<br />
<br />
7.HashMap的Generics<br />
//Example&nbsp;17<br />
public&nbsp;class&nbsp;HashDemoGeneric&nbsp;{<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;HashMap&lt;Integer,String&gt;&nbsp;map&nbsp;=&nbsp;new&nbsp;HashMap&lt;Integer,String&gt;();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;map.put(1,&nbsp;"Ian");<br />
&nbsp;&nbsp;&nbsp;&nbsp;map.put(42,&nbsp;"Scott");<br />
&nbsp;&nbsp;&nbsp;&nbsp;map.put(123,&nbsp;"Somebody&nbsp;else");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name&nbsp;=&nbsp;map.get(42);<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(name);<br />
&nbsp;&nbsp;}<br />
}&nbsp;<br />
<br />
<br />
8.接口的Generics<br />
//Example&nbsp;18<br />
interface&nbsp;MinMax&lt;T&nbsp;extends&nbsp;Comparable&lt;T&gt;&gt;&nbsp;{&nbsp;<br />
&nbsp;&nbsp;T&nbsp;min();&nbsp;<br />
&nbsp;&nbsp;T&nbsp;max();&nbsp;<br />
}&nbsp;<br />
//&nbsp;Now,&nbsp;implement&nbsp;MinMax&nbsp;<br />
class&nbsp;MyClass&lt;T&nbsp;extends&nbsp;Comparable&lt;T&gt;&gt;&nbsp;implements&nbsp;MinMax&lt;T&gt;&nbsp;{&nbsp;<br />
&nbsp;&nbsp;T[]&nbsp;vals;&nbsp;<br />
&nbsp;&nbsp;MyClass(T[]&nbsp;o)&nbsp;{&nbsp;vals&nbsp;=&nbsp;o;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;//&nbsp;Return&nbsp;the&nbsp;minimum&nbsp;value&nbsp;in&nbsp;vals.&nbsp;<br />
&nbsp;&nbsp;public&nbsp;T&nbsp;min()&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;v&nbsp;=&nbsp;vals[0];&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=1;&nbsp;i&nbsp;&lt;&nbsp;vals.length;&nbsp;i++)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(vals[i].compareTo(v)&nbsp;&lt;&nbsp;0)&nbsp;v&nbsp;=&nbsp;vals[i];&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;v;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;//&nbsp;Return&nbsp;the&nbsp;maximum&nbsp;value&nbsp;in&nbsp;vals.&nbsp;<br />
&nbsp;&nbsp;public&nbsp;T&nbsp;max()&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;v&nbsp;=&nbsp;vals[0];&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=1;&nbsp;i&nbsp;&lt;&nbsp;vals.length;&nbsp;i++)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(vals[i].compareTo(v)&nbsp;&gt;&nbsp;0)&nbsp;v&nbsp;=&nbsp;vals[i];&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;v;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
}&nbsp;<br />
public&nbsp;class&nbsp;GenIFDemo&nbsp;{&nbsp;<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;args[])&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Integer&nbsp;inums[]&nbsp;=&nbsp;{3,&nbsp;6,&nbsp;2,&nbsp;8,&nbsp;6&nbsp;};&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Character&nbsp;chs[]&nbsp;=&nbsp;{'b',&nbsp;'r',&nbsp;'p',&nbsp;'w'&nbsp;};&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;MyClass&lt;Integer&gt;&nbsp;iob&nbsp;=&nbsp;new&nbsp;MyClass&lt;Integer&gt;(inums);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;MyClass&lt;Character&gt;&nbsp;cob&nbsp;=&nbsp;new&nbsp;MyClass&lt;Character&gt;(chs);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Max&nbsp;value&nbsp;in&nbsp;inums:&nbsp;"&nbsp;+&nbsp;iob.max());&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Min&nbsp;value&nbsp;in&nbsp;inums:&nbsp;"&nbsp;+&nbsp;iob.min());&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Max&nbsp;value&nbsp;in&nbsp;chs:&nbsp;"&nbsp;+&nbsp;cob.max());&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Min&nbsp;value&nbsp;in&nbsp;chs:&nbsp;"&nbsp;+&nbsp;cob.min());&nbsp;<br />
&nbsp;&nbsp;}&nbsp;<br />
}<br />
<br />
<br />
9.Exception的Generics<br />
//Example&nbsp;20<br />
interface&nbsp;Executor&lt;E&nbsp;extends&nbsp;Exception&gt;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;execute()&nbsp;throws&nbsp;E;<br />
}<br />
<br />
public&nbsp;class&nbsp;GenericExceptionTest&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;args[])&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executor&lt;IOException&gt;&nbsp;e&nbsp;=<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;Executor&lt;IOException&gt;()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;execute()&nbsp;throws&nbsp;IOException<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;code&nbsp;here&nbsp;that&nbsp;may&nbsp;throw&nbsp;an<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;IOException&nbsp;or&nbsp;a&nbsp;subtype&nbsp;of<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;IOException<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.execute();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch(IOException&nbsp;ioe)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("IOException:&nbsp;"&nbsp;+&nbsp;ioe);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ioe.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}&nbsp;&nbsp;&nbsp;</span></p>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311970.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:26 <a href="http://www.blogjava.net/JeromeKwok/articles/311970.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>初试Filter对权限和session的控制</title><link>http://www.blogjava.net/JeromeKwok/articles/311969.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:22:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311969.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311969.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311969.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311969.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311969.html</trackback:ping><description><![CDATA[<div class="postTitle"><span style="font-family: Courier New; font-size: x-small">用Filter防止用户访问一些未被授权的资源,比如一个用户未登录就不允许访问网站的某些页面，并将页面重定向到需要用户登录的页面，下面是一个相关的例子：<br />
</span></div>
<div class="postText">
<p><span style="font-family: Courier New; font-size: x-small">package com.drp.util.filter;</span></p>
<p><span style="font-family: Courier New; font-size: x-small">import java.io.IOException;</span></p>
<p><span style="font-family: Courier New; font-size: x-small">import javax.servlet.Filter;<br />
import javax.servlet.FilterChain;<br />
import javax.servlet.FilterConfig;<br />
import javax.servlet.ServletException;<br />
import javax.servlet.ServletRequest;<br />
import javax.servlet.ServletResponse;<br />
import javax.servlet.http.HttpServletRequest;<br />
import javax.servlet.http.HttpServletResponse;<br />
import javax.servlet.http.HttpSession;</span></p>
<p><span style="font-family: Courier New; font-size: x-small">public class AuthFilter implements Filter {<br />
&nbsp;<br />
&nbsp;public void destroy() {</span></p>
<p><span style="font-family: Courier New; font-size: x-small">&nbsp;}</span></p>
<p><span style="font-family: Courier New; font-size: x-small">&nbsp;public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,<br />
&nbsp;&nbsp;&nbsp;FilterChain filterChain) throws IOException, ServletException {//</span><span style="font-family: Courier New"><span style="font-size: x-small"><span style="color: #008000" mce_style="COLOR: #008000">1,doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息（包括表单数据、cookie和HTTP请求头）的完全访问。第二个参数为ServletResponse，通常在简单的过滤器中忽略此参数。最后一个参数为FilterChain，此参数用来调用servlet或JSP页。<br />
</span><br />
&nbsp;&nbsp;HttpServletRequest request = (HttpServletRequest)servletRequest;//;<span style="color: #008000" mce_style="COLOR: #008000">//如果处理HTTP请求，并且需要访问诸如getHeader或getCookies等在ServletRequest中无法得到的方法，就要把此request对象构造成HttpServletRequest</span><br />
&nbsp;&nbsp;HttpServletResponse response = (HttpServletResponse)servletResponse</span></span><span style="color: #008000" mce_style="COLOR: #008000"><span style="font-family: Courier New; font-size: x-small">。<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: x-small">&nbsp;&nbsp;String currentURL = request.getRequestURI();//<span style="color: #008000" mce_style="COLOR: #008000">取得根目录所对应的绝对路径:</span><br />
<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;String targetURL = currentURL.substring(currentURL.indexOf("/", 1), currentURL.length());&nbsp;&nbsp;</span><span style="font-family: Courier New"><span style="font-size: x-small"><span style="color: #008000" mce_style="COLOR: #008000">//截取到当前文件名用于比较<br />
</span><br />
&nbsp;&nbsp;HttpSession session = request.getSession(false);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;if (!"/login.jsp".equals(targetURL)) {//</span></span><span style="font-family: Courier New"><span style="font-size: x-small"><span style="color: #008000" mce_style="COLOR: #008000">判断当前页是否是重定向以后的登录页面页面，如果是就不做session的判断，防止出现死循环<br />
</span>&nbsp;&nbsp;&nbsp;if (session == null || session.getAttribute("user") == null) {//<span style="color: #ff0000" mce_style="COLOR: #ff0000">*用户登录以后需手动添加session</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("request.getContextPath()=" + request.getContextPath());<br />
&nbsp;&nbsp;&nbsp;&nbsp;response.sendRedirect(request.getContextPath() + "/login.jsp");//</span></span><span style="font-family: Courier New"><span style="font-size: x-small"><span style="color: #008000" mce_style="COLOR: #008000">如果session为空表示用户没有登录就重定向到login.jsp页面<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;return;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;//加入filter链继续向下执行<br />
&nbsp;&nbsp;filterChain.doFilter(request, response);//.</span></span><span style="font-family: Courier New"><span style="font-size: x-small"><span style="color: #008000" mce_style="COLOR: #008000">调用FilterChain对象的doFilter方法。Filter接口的doFilter方法取一个FilterChain对象作为它的一个参数。在调用此对象的doFilter方法时，激活下一个相关的过滤器。如果没有另一个过滤器与servlet或JSP页面关联，则servlet或JSP页面被激活。<br />
</span><br />
&nbsp;}</span></span></p>
<p><span style="font-family: Courier New; font-size: x-small">&nbsp;public void init(FilterConfig filterConfig) throws ServletException {</span></p>
<p><span style="font-family: Courier New; font-size: x-small">&nbsp;}<br />
}<br />
</span><span style="font-family: Courier New"><span style="font-size: x-small"><span style="color: #008000" mce_style="COLOR: #008000"><span style="color: #ff0000" mce_style="COLOR: #ff0000">然后在配置文件web.xml里添加： （请注意，过滤是在serlvet规范2.3版中初次引入的。因此，web.xml文件必须使用DTD的2.3以上版本。） <br />
</span></span>&lt;filter&gt;<br />
&nbsp; &nbsp;&lt;filter-name&gt;AuthFilter&lt;/filter-name&gt;<br />
&nbsp; &nbsp;&lt;filter-class&gt;com.drp.util.filter.AuthFilter&lt;/filter-class&gt;<br />
&nbsp;&lt;/filter&gt;<br />
&nbsp;&nbsp;<br />
&nbsp;&lt;filter-mapping&gt;<br />
&nbsp; &nbsp;&lt;filter-name&gt;AuthFilter&lt;/filter-name&gt;<br />
&nbsp; &nbsp;&lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;//<span style="color: #008000" mce_style="COLOR: #008000">表示对所有jsp文件有效</span><br />
&nbsp;&lt;/filter-mapping&gt;<br />
</span></span></p>
<span style="font-family: Courier New; font-size: x-small">这样用户没有登录的情况下就会转到登录页面。&nbsp;</span></div>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311969.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:22 <a href="http://www.blogjava.net/JeromeKwok/articles/311969.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java版通用JS级联</title><link>http://www.blogjava.net/JeromeKwok/articles/311967.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:18:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311967.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311967.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311967.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311967.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311967.html</trackback:ping><description><![CDATA[<p class="postText"><span style="font-family: Courier New; font-size: x-small">在开发中，经常遇到诸如省、市，大类、小类的级联select 下拉框。常常，这些类别或地区的内容，又存在数据库中。因为用户希望，一切都是可控制的。那么，如果涉及到这种级联的地方，每次都人从库中读取，在JSP中要写很多代码去读表。另外，这种级联在修改数据的时候，应设置的选中项为库中所载，这也是需要写一些代码的。<br />
<br />
这里本人建议，通过IO，将类别生成js文件，然后在页面中引入这个js文件，这样即提高的程序的运用速度，又精简了的代码书写量。<br />
<br />
<strong>一、表结构如下：</strong><br />
<br />
create table&nbsp; news_class200<br />
(<br />
id int primary key,<br />
parent_id int,<br />
class_name varchar(20),<br />
orderby int default 0</span></p>
<p class="postText"><span style="font-family: Courier New; font-size: x-small">)<br />
<br />
id 为自动增长<br />
parent_id 用来标识父类的id<br />
class_name 类别名称<br />
orderby 排序，用来控制select中元素的前后顺序<br />
<br />
<strong>二、成生js的java代码：</strong><br />
<br />
&nbsp;public static void news_class(String str,String tab) throws IOException<br />
&nbsp;{<br />
&nbsp;&nbsp;//大类名称<br />
&nbsp;&nbsp;String big="big_class";<br />
&nbsp;&nbsp;String small="small_class";<br />
&nbsp;&nbsp;String big_array="";<br />
&nbsp;&nbsp;String[] small_array;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; Jdata data = new Jdata();//dao对象<br />
&nbsp;&nbsp;&nbsp;&nbsp; List list = data.jlist("select * from "+tab+" where parent_id=0");<br />
&nbsp;&nbsp;&nbsp;&nbsp; FileWriter fw = new FileWriter(str);<br />
&nbsp;&nbsp;&nbsp;&nbsp; PrintWriter out = new PrintWriter(fw);<br />
&nbsp;&nbsp;&nbsp;&nbsp; List ll = new ArrayList();<br />
&nbsp;&nbsp;&nbsp;&nbsp; small_array=new String[list.size()];<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;list.size();i++)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;//读取大类信息<br />
&nbsp;&nbsp;&nbsp; Map map=(Map)list.get(i);<br />
&nbsp;&nbsp;&nbsp; big_array+="'"+map.get("class_name")+"',";<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; ll=data.jlist("select * from "+tab+" where parent_id="+map.get("id"));<br />
&nbsp;&nbsp;&nbsp; small_array[i]="";<br />
&nbsp;&nbsp;&nbsp; for(int j=0;j&lt;ll.size();j++)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;Map m =(Map)ll.get(j);<br />
&nbsp;&nbsp;&nbsp;&nbsp;small_array[i]+="'"+m.get("class_name")+"',";&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; small_array[i]=noEnd(small_array[i]);<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;// System.out.println(big_array);<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; big_array=noEnd(big_array);<br />
&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p class="postText"><span style="font-family: Courier New; font-size: x-small">&nbsp;&nbsp;&nbsp; // out.println("&lt;script language=javascript&gt;");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("document.writeln(\'&lt;select name="+big+" onchange=\\\""+small+"MM(this.selectedIndex)\\\"&gt;\');");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("document.writeln('&lt;option value=\\\"</span><a><span style="font-family: Courier New; font-size: x-small">\\\</span></a><span style="font-family: Courier New; font-size: x-small">"&gt;请选择&lt;/option&gt;');");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("document.writeln('&lt;/select&gt;');");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("document.writeln('&lt;select name="+small+"&gt;');");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("document.writeln('&lt;option value=\\\"</span><a><span style="font-family: Courier New; font-size: x-small">\\\</span></a><span style="font-family: Courier New; font-size: x-small">"&gt;请选择&lt;/option&gt;');");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("document.writeln('&lt;/select&gt;');");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("var "+big+"Name = ["+big_array+"];");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(" var "+big+"Value=["+big_array+"];");<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; for(int m=0;m&lt;small_array.length;m++)&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&nbsp; var "+small+(m+1)+" = ["+small_array[m]+"];");<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("function "+big+"() {");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("&nbsp; var e = document.getElementById('"+big+"');");//000<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(" for (var i=0; i&lt;"+big+"Name.length; i++)");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(" e.options.add(new Option("+big+"Name[i], "+big+"Value[i]));");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(" }");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(" function "+small+"MM(n){");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(" var e = document.getElementById('"+small+"');");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("e.options.length = 1;");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("if (n == 0) return;");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(" var a = eval('"+small+"'+ n);");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(" for (var i=0; i&lt;a.length; i++) e.options.add(new Option(a[i], a[i]));");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println("}");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println(big+"();");<br />
&nbsp;&nbsp;&nbsp;&nbsp; //out.println(" window.attachEvent('onload', "+big+"); ");<br />
&nbsp;&nbsp;&nbsp;&nbsp; //out.println(" &lt;/script&gt;");<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.flush();<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp; fw.close();<br />
&nbsp;&nbsp;<br />
&nbsp;}<br />
&nbsp;<br />
<br />
<strong>三、生成的js如下：</strong><br />
<br />
document.writeln('&lt;select name=big_class onchange=\"small_classMM(this.selectedIndex)\"&gt;');<br />
document.writeln('&lt;option value=\"\"&gt;请选择&lt;/option&gt;');<br />
document.writeln('&lt;/select&gt;');<br />
document.writeln('&lt;select name=small_class&gt;');<br />
document.writeln('&lt;option value=\"\"&gt;请选择&lt;/option&gt;');<br />
document.writeln('&lt;/select&gt;');<br />
&nbsp;var big_className = ['县域动态','省域见闻','国外新闻'];<br />
&nbsp;var big_classValue=['县域动态','省域见闻','国外新闻'];<br />
&nbsp; var small_class1 = ['A类',''B类,'C类'];<br />
&nbsp; var small_class2 = ['无小类'];<br />
&nbsp; var small_class3 = ['无'];<br />
function big_class() {<br />
&nbsp; var e = document.getElementById('big_class');<br />
&nbsp;for (var i=0; i&lt;big_className.length; i++)<br />
&nbsp;e.options.add(new Option(big_className[i], big_classValue[i]));<br />
&nbsp;}<br />
&nbsp;function small_classMM(n){<br />
&nbsp;var e = document.getElementById('small_class');<br />
e.options.length = 1;<br />
if (n == 0) return;<br />
&nbsp;var a = eval('small_class'+ n);<br />
&nbsp;for (var i=0; i&lt;a.length; i++) e.options.add(new Option(a[i], a[i]));<br />
}<br />
big_class();<br />
&nbsp;</span></p>
<img src ="http://www.blogjava.net/JeromeKwok/aggbug/311967.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:18 <a href="http://www.blogjava.net/JeromeKwok/articles/311967.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Java实现几种常见的排序算法</title><link>http://www.blogjava.net/JeromeKwok/articles/311965.html</link><dc:creator>Jerome Kwok</dc:creator><author>Jerome Kwok</author><pubDate>Thu, 04 Feb 2010 07:14:00 GMT</pubDate><guid>http://www.blogjava.net/JeromeKwok/articles/311965.html</guid><wfw:comment>http://www.blogjava.net/JeromeKwok/comments/311965.html</wfw:comment><comments>http://www.blogjava.net/JeromeKwok/articles/311965.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/JeromeKwok/comments/commentRss/311965.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/JeromeKwok/services/trackbacks/311965.html</trackback:ping><description><![CDATA[<pre>用Java语言实现的各种排序，包括插入排序、冒泡排序、选择排序、Shell排序、快速排序、归并排序、堆排序、</pre>
<pre>SortUtil等。 </pre>
<pre clear="both">插入排序：</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
import org.rut.util.algorithm.SortUtil;</pre>
<pre class="code">/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class InsertSort implements SortUtil.Sort{<br />
<br />
&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=1;i&lt;data.length;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int j=i;(j&gt;0)&amp;&amp;(data[j]&lt;data[j-1]);j--){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,j,j-1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}</pre>
<pre>冒泡排序：</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
<br />
import org.rut.util.algorithm.SortUtil;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class BubbleSort implements SortUtil.Sort{<br />
<br />
&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;data.length;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int j=data.length-1;j&gt;i;j--){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(data[j]&lt;data[j-1]){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,j,j-1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}</pre>
<pre>选择排序：</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
<br />
import org.rut.util.algorithm.SortUtil;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class SelectionSort implements SortUtil.Sort {<br />
<br />
&nbsp;&nbsp;&nbsp; /*<br />
&nbsp;&nbsp;&nbsp;&nbsp; * (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * <br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; data.length; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int lowIndex = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j = data.length - 1; j &gt; i; j--) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (data[j] &lt; data[lowIndex]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lowIndex = j;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,i,lowIndex);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}</pre>
<pre>Shell排序：</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
<br />
import org.rut.util.algorithm.SortUtil;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class ShellSort implements SortUtil.Sort{<br />
<br />
&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=data.length/2;i&gt;2;i/=2){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int j=0;j&lt;i;j++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertSort(data,j,i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertSort(data,0,1);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param data<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param j<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param i<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; private void insertSort(int[] data, int start, int inc) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=start+inc;i&lt;data.length;i+=inc){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int j=i;(j&gt;=inc)&amp;&amp;(data[j]&lt;data[j-inc]);j-=inc){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,j,j-inc);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}</pre>
<pre>&nbsp;</pre>
<pre>快速排序：</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
<br />
import org.rut.util.algorithm.SortUtil;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class QuickSort implements SortUtil.Sort{<br />
<br />
&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; quickSort(data,0,data.length-1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; private void quickSort(int[] data,int i,int j){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int pivotIndex=(i+j)/2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //swap<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,pivotIndex,j);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int k=partition(data,i-1,j,data[j]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,k,j);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((k-i)&gt;1) quickSort(data,i,k-1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((j-k)&gt;1) quickSort(data,k+1,j);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param data<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param i<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param j<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @return<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; private int partition(int[] data, int l, int r,int pivot) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(data[++l]&lt;pivot);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while((r!=0)&amp;&amp;data[--r]&gt;pivot);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,l,r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(l&lt;r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,l,r);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return l;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}</pre>
<pre>改进后的快速排序：</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
<br />
import org.rut.util.algorithm.SortUtil;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class ImprovedQuickSort implements SortUtil.Sort {<br />
<br />
&nbsp;&nbsp;&nbsp; private static int MAX_STACK_SIZE=4096;<br />
&nbsp;&nbsp;&nbsp; private static int THRESHOLD=10;<br />
&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int[] stack=new int[MAX_STACK_SIZE];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int top=-1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int pivot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int pivotIndex,l,r;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack[++top]=0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack[++top]=data.length-1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(top&gt;0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int j=stack[top--];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i=stack[top--];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pivotIndex=(i+j)/2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pivot=data[pivotIndex];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,pivotIndex,j);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //partition<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l=i-1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r=j;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(data[++l]&lt;pivot);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while((r!=0)&amp;&amp;(data[--r]&gt;pivot));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,l,r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(l&lt;r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,l,r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,l,j);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((l-i)&gt;THRESHOLD){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack[++top]=i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack[++top]=l-1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((j-l)&gt;THRESHOLD){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack[++top]=l+1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack[++top]=j;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //new InsertSort().sort(data);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertSort(data);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param data<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; private void insertSort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=1;i&lt;data.length;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int j=i;(j&gt;0)&amp;&amp;(data[j]&lt;data[j-1]);j--){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,j,j-1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}</pre>
<pre>归并排序：</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
<br />
import org.rut.util.algorithm.SortUtil;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class MergeSort implements SortUtil.Sort{<br />
<br />
&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int[] temp=new int[data.length];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mergeSort(data,temp,0,data.length-1);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; private void mergeSort(int[] data,int[] temp,int l,int r){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int mid=(l+r)/2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(l==r) return ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mergeSort(data,temp,l,mid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mergeSort(data,temp,mid+1,r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=l;i&lt;=r;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp[i]=data[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i1=l;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i2=mid+1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int cur=l;cur&lt;=r;cur++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(i1==mid+1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[cur]=temp[i2++];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(i2&gt;r)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[cur]=temp[i1++];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(temp[i1]&lt;temp[i2])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[cur]=temp[i1++];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[cur]=temp[i2++];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}</pre>
<pre>改进后的归并排序:</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
<br />
import org.rut.util.algorithm.SortUtil;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class ImprovedMergeSort implements SortUtil.Sort {<br />
<br />
&nbsp;&nbsp;&nbsp; private static final int THRESHOLD = 10;<br />
<br />
&nbsp;&nbsp;&nbsp; /*<br />
&nbsp;&nbsp;&nbsp;&nbsp; * (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * <br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int[] temp=new int[data.length];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mergeSort(data,temp,0,data.length-1);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; private void mergeSort(int[] data, int[] temp, int l, int r) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i, j, k;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int mid = (l + r) / 2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (l == r)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((mid - l) &gt;= THRESHOLD)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mergeSort(data, temp, l, mid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertSort(data, l, mid - l + 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((r - mid) &gt; THRESHOLD)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mergeSort(data, temp, mid + 1, r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertSort(data, mid + 1, r - mid);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = l; i &lt;= mid; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp[i] = data[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (j = 1; j &lt;= r - mid; j++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp[r - j + 1] = data[j + mid];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int a = temp[l];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int b = temp[r];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = l, j = r, k = l; k &lt;= r; k++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (a &lt; b) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[k] = temp[i++];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a = temp[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[k] = temp[j--];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = temp[j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param data<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param l<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param i<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; private void insertSort(int[] data, int start, int len) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=start+1;i&lt;start+len;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int j=i;(j&gt;start) &amp;&amp; data[j]&lt;data[j-1];j--){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(data,j,j-1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }</pre>
<pre>}</pre>
<pre>堆排序：</pre>
<pre class="code">package org.rut.util.algorithm.support;<br />
<br />
import org.rut.util.algorithm.SortUtil;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class HeapSort implements SortUtil.Sort{<br />
<br />
&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MaxHeap h=new MaxHeap();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h.init(data);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;data.length;i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h.remove();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.arraycopy(h.queue,1,data,0,data.length);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; private static class MaxHeap{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void init(int[] data){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.queue=new int[data.length+1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;data.length;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queue[++size]=data[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fixUp(size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int size=0;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int[] queue;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int get() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return queue[1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void remove() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(queue,1,size--);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fixDown(1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //fixdown<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void fixDown(int k) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int j;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((j = k &lt;&lt; 1) &lt;= size) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (j &lt; size &amp;&amp; queue[j]&lt;queue[j+1])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j++; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (queue[k]&gt;queue[j]) //不用交换<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(queue,j,k);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k = j;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void fixUp(int k) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (k &gt; 1) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int j = k &gt;&gt; 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (queue[j]&gt;queue[k])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SortUtil.swap(queue,j,k);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k = j;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}</pre>
<pre>SortUtil：</pre>
<pre class="code">package org.rut.util.algorithm;<br />
<br />
import org.rut.util.algorithm.support.BubbleSort;<br />
import org.rut.util.algorithm.support.HeapSort;<br />
import org.rut.util.algorithm.support.ImprovedMergeSort;<br />
import org.rut.util.algorithm.support.ImprovedQuickSort;<br />
import org.rut.util.algorithm.support.InsertSort;<br />
import org.rut.util.algorithm.support.MergeSort;<br />
import org.rut.util.algorithm.support.QuickSort;<br />
import org.rut.util.algorithm.support.SelectionSort;<br />
import org.rut.util.algorithm.support.ShellSort;<br />
<br />
/**<br />
&nbsp;* @author treeroot<br />
&nbsp;* @since 2006-2-2<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class SortUtil {<br />
&nbsp;&nbsp;&nbsp; public final static int INSERT = 1;<br />
&nbsp;&nbsp;&nbsp; public final static int BUBBLE = 2;<br />
&nbsp;&nbsp;&nbsp; public final static int SELECTION = 3;<br />
&nbsp;&nbsp;&nbsp; public final static int SHELL = 4;<br />
&nbsp;&nbsp;&nbsp; public final static int QUICK = 5;<br />
&nbsp;&nbsp;&nbsp; public final static int IMPROVED_QUICK = 6;<br />
&nbsp;&nbsp;&nbsp; public final static int MERGE = 7;<br />
&nbsp;&nbsp;&nbsp; public final static int IMPROVED_MERGE = 8;<br />
&nbsp;&nbsp;&nbsp; public final static int HEAP = 9;<br />
<br />
&nbsp;&nbsp;&nbsp; public static void sort(int[] data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sort(data, IMPROVED_QUICK);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; private static String[] name={<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "insert", "bubble", "selection", "shell", "quick", </pre>
<pre class="code">"improved_quick", "merge", "improved_merge", "heap"<br />
&nbsp;&nbsp;&nbsp; };<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; private static Sort[] impl=new Sort[]{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new InsertSort(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new BubbleSort(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new SelectionSort(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ShellSort(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new QuickSort(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ImprovedQuickSort(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new MergeSort(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ImprovedMergeSort(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new HeapSort()<br />
&nbsp;&nbsp;&nbsp; };<br />
<br />
&nbsp;&nbsp;&nbsp; public static String toString(int algorithm){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name[algorithm-1];<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; public static void sort(int[] data, int algorithm) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; impl[algorithm-1].sort(data);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public static interface Sort {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void sort(int[] data);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public static void swap(int[] data, int i, int j) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp = data[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i] = data[j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[j] = temp;<br />
&nbsp;&nbsp;&nbsp; }<br />
}</pre>
<pre class="code">&nbsp;</pre>
 <img src ="http://www.blogjava.net/JeromeKwok/aggbug/311965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/JeromeKwok/" target="_blank">Jerome Kwok</a> 2010-02-04 15:14 <a href="http://www.blogjava.net/JeromeKwok/articles/311965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>