﻿<?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-Jiangshachina-随笔分类-CoreJavaTechTips</title><link>http://www.blogjava.net/jiangshachina/category/30635.html</link><description>同是Java爱好者，相逢何必曾相识！&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;a cup of Java, cheers!</description><language>zh-cn</language><lastBuildDate>Sat, 03 Aug 2013 17:43:24 GMT</lastBuildDate><pubDate>Sat, 03 Aug 2013 17:43:24 GMT</pubDate><ttl>60</ttl><item><title>在泛型中使用通配符和继承(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2009/12/28/307495.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Mon, 28 Dec 2009 05:44:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2009/12/28/307495.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/307495.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2009/12/28/307495.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/307495.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/307495.html</trackback:ping><description><![CDATA[<div align="center"><span style="font-size: 10pt;"><strong><span style="font-size: 14pt;">在泛型中使用通配符和继承</span></strong></span><br />
</div>
&nbsp;&nbsp;&nbsp; <span style="font-size: 10pt;">本文是Sun官方以Blog形式发布的Java核心技术窍门(<a href="http://blogs.sun.com/CoreJavaTechTips/">JavaCoreTechTip</a>)中的<a href="http://blogs.sun.com/CoreJavaTechTips/entry/using_generics_with_wildcards_and">一篇</a>，它以非常简洁的示例展示了泛型通配符的使用，初学Java泛型的朋友可以看看。(2009.12.30最后更新)<br />
&nbsp;&nbsp;&nbsp; Java2平台，标准版5.0(J2SE 5.0)为Java程序设计语言及其平台引入了泛型。在最简单的案例和典型的应用中，泛型能够识别集合容器中所存储的是否是你所期望的对象。所以，你可以特别说你有一个String或其它类型对象的List，而不是声称你的程序有一个Object的List。所以，如果你不小心向该List中加入了错误类型的对象，编译器会告之你这个错误。该错误将在编译时进行修复，而不用等到你运行该程序，且在程序运行到该处代码时，在获取对象的操作中产生一个运行时的强制类型转换异常。<br />
这就提出了泛型的第二个好处。迭代器将变得类型安全了。Iterator接口中的next()方法将会返回集合中下一个元素的类型安全版本。<br />
&nbsp;&nbsp;&nbsp; 但这并不是本文要介绍的泛型应用的窍门，那些窍门已由<a href="http://java.sun.com/developer/JDCTechTips/2005/tt0315.html#1">2005 Core Java Technologies Tip</a>描述过了。在使用泛型时，大多数人都不能很好地理解对extends关键字的使用。一个典型的描述如何使用<span style="font-family: Courier;">extends</span>关键字的示例与绘制图形有关。与其不同的是，此处窍门所用的示例将使用Swing组件，以便你不必创建额外的新类。在一个非常有限的例子中，Swing按钮组件的类层次结构如下所示，当然，Object是实际上的根。<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">Component<br />
</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;Container<br />
&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JComponent<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;AbstractButton<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JButton<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JMenuItem<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JCheckBoxMenuItem<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JMenu<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JRadioButtonMenuItem<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JToggleButton<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JCheckBox<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">|-</span><span style="color: rgb(0, 0, 0);">&nbsp;JRadioButton</span></div>
<span style="font-size: 10pt;"><br />
&nbsp;&nbsp;&nbsp; 所有AbstractButton的子类都共同享有的一个东西就是方法getText。这就是泛型的精髓，你能定义一个方法去处理以AbstractButton为元素的List，并返回这些按钮的String类型的标签的List。下面是该方法的第一个版本：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;getLabels(List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">AbstractButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;list)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;labelList&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ArrayList</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">(list.size());<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(AbstractButton&nbsp;button:&nbsp;list)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;labelList.add(button.getText());<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;labelList;<br />
}</span></div>
<span style="font-size: 10pt;"><br />
&nbsp;&nbsp;&nbsp; 下面就是如何使用该方法。首先，定义一个AbstractButton类型的List，然后向其中填充值，并调用该方法：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">AbstractButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;buttonList&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ArrayList</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">AbstractButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">();<br />
buttonList.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JButton(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
buttonList.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JCheckBox(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">World</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
buttonList.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JRadioButton(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hola</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
buttonList.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JMenuItem(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Mundo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
<br />
List&nbsp;labels&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;getLabels(buttonList);<br />
System.out.println(labels);</span></div>
<span style="font-size: 10pt;"><br />
&nbsp;&nbsp;&nbsp; 根据Google，"Hola, Mundo"是"Hello, World"的西班牙译文。调用println()方法的结果如下所示： <br />
[Hello, World, Hola, Mundo]<br />
<br />
&nbsp;&nbsp;&nbsp; 对于<span style="font-family: Courier;">AbstractButton</span>的<span style="font-family: Courier;">List</span>对象，一切都能正常运行，但当是其它类型，特别是AbstractButton子类型的List时，就不能正常工作了。从逻辑上，有人可能认为对于以JButton为元素的List，一切仍能正常工作。因为JButton是AbstractButton的子类。难道不能对AbstractButton子类型的List调用方法<span style="font-family: 宋体;">getLabels(List&lt;AbstractButton&gt;)</span>？<br />
然而，事实并非如此。因为这是一个编译时检查，同时也因为getLabels方法被定义为只接受AbstractButton的List，你不能向该方法中传入任何其它类型的List。<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">GetList.java:</span><span style="color: rgb(0, 0, 0);">13</span><span style="color: rgb(0, 0, 0);">:&nbsp;getLabels(java.util.List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">javax.swing.AbstractButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">)<br />
&nbsp;&nbsp;in&nbsp;GetList&nbsp;cannot&nbsp;be&nbsp;applied&nbsp;to&nbsp;(java.util.List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">javax.swing.JButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;labels&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;getLabels(buttonList);<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;&nbsp;</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">&nbsp;error</span></div>
<span style="font-size: 10pt;"><br />
这也就是extends关键字发挥作用的地方了。不将<span style="font-family: Courier;">getLabes</span>方法定义为仅仅接受<span style="font-family: Courier;">AbstractButton</span> <span style="font-family: Courier;">List</span>，而是将它定义为接受<span style="font-family: Courier;">AbstractButton</span>子类的<span style="font-family: Courier;">List</span>：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;getLabels(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);">&nbsp;AbstractButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;list)</span></div>
<span style="font-size: 10pt;"><br />
此处的通配符?表明该方法并不关心确切的类型是什么，只要它是AbstractButton的子类型即可。下面是综合了前述所有代码片断的完整示例程序：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;javax.swing.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;GetList&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;main(String&nbsp;args[])&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">JButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;buttonList&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ArrayList</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">JButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buttonList.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JButton(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buttonList.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JButton(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">World</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buttonList.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JButton(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hola</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buttonList.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JButton(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Mundo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;labels&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;getLabels(buttonList);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(labels);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;getLabels(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);">&nbsp;AbstractButton</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;list)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;labelList&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ArrayList</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">(list.size());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(AbstractButton&nbsp;button:&nbsp;list)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;labelList.add(button.getText());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;labelList;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<span style="font-size: 10pt;"><br />
现在，当你要用泛型来定义你自己的类和方法时，就要考虑接受作为泛型参数的抽象类，或它的任一超类，记得使用通配符以便相同的方法对于子类也能很好地工作。<br />
更多关于泛型的信息，请见两篇较早前由Gilad Bracha撰写的教程：一篇是<a href="http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf">2004年的教程(PDF)</a>，另一篇是在线的<a href="http://java.sun.com/docs/books/tutorial/extra/generics/">Java Tutorial</a>中的泛型章节。<br />
<br />
</span>
<img src ="http://www.blogjava.net/jiangshachina/aggbug/307495.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2009-12-28 13:44 <a href="http://www.blogjava.net/jiangshachina/archive/2009/12/28/307495.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Callable返回结果(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204007.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Sat, 31 May 2008 14:24:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204007.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/204007.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/204007.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/204007.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 10pt;"><span style="font-size: 14pt;">使用Callable返回结果</span></span></strong><br />
</div>
<span style="font-size: 10pt;">
&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">本文是Sun官方以Blog形式发布的Java核心技术窍门(<a href="http://blogs.sun.com/CoreJavaTechTips/">JavaCoreTechTip</a>)中的一个。本文主要介绍了Callable及其相关接口和类的使用，篇幅不长且易于理解，故翻译在了此处，相信对于准备或刚接触java.util.concurrent的朋友会有所帮助。(2008.05.31最后更新)<br />
<br />
</span><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 自从Java平台的最开始，Runnable接口就已存在了。它允许你定义一个可由线程完成的任务。如大多数人所已知的那样，它只提供了一个run方法，该方法既不接受任何参数，也不返回任何值。如果你需要从一个未完成的任务中返回一个值，你就必须在该接口之外使用一个方法去等待该任务完成时通报的某种消息。例如，下面的示例就是你在这种情景下可能做的事情：<br />
&nbsp;&nbsp;&nbsp; Runnable runnable = ...;<br />
&nbsp;&nbsp;&nbsp; Thread t = new Thread(runnable);<br />
&nbsp;&nbsp;&nbsp; t.start();<br />
&nbsp;&nbsp;&nbsp; t.join();<br />
&nbsp;&nbsp;&nbsp; String value = someMethodtoGetSavedValue()<br />
严格来说，上述代码并无错误，但现在可用不同的方法去做，这要感谢J2SE 5.0引入的Callable接口。不同于Runnable接口拥有run方法，Callable接口提供的是call方法，该方法可以返回一个Object对象，或可返回任何一个在泛型化格式中定义了的特定类型的对象。<br />
&nbsp;&nbsp;&nbsp; public interface Callable&lt;V&gt; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; V call() throws Exception;<br />
&nbsp;&nbsp;&nbsp; }<br />
因为你不可能把Callable对象传到Thread对象去执行，你可换用ExecutorService对象去执行Callable对象。该服务接受Callable对象，并经由submit方法去执行它。<br />
&nbsp;&nbsp;&nbsp; &lt;T&gt; Future&lt;T&gt; submit(Callable&lt;T&gt; task)<br />
如该方法的定义所示，提交一个Callable对象给ExecutorService会返回一个Future对象。然后，Future的get方法将会阻塞，直到任务完成。<br />
&nbsp;&nbsp;&nbsp; 为了证明这一点，下面的例子为命令行中的每个词都创建一个单独的Callable实例，然后把这些词的长度加起来。各个Callable对象将只是计算它自己的词的长度之和。Futures对象的Set集合将被保存以便从中获得计算用的值。如果需要保持返回值的顺序，则可换用一个List对象。</span><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.util.</span><span style="color: #000000; ">*</span><span style="color: #000000; ">;<br /></span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.util.concurrent.</span><span style="color: #000000; ">*</span><span style="color: #000000; ">;<br /><br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;CallableExample&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;WordLengthCallable<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">implements</span><span style="color: #000000; ">&nbsp;Callable&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;String&nbsp;word;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;WordLengthCallable(String&nbsp;word)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.word&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;word;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;Integer&nbsp;call()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;Integer.valueOf(word.length());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;main(String&nbsp;args[])&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExecutorService&nbsp;pool&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;Executors.newFixedThreadPool(</span><span style="color: #000000; ">3</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Future</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Integer</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">&nbsp;set&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;HashSet</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Future</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">lg;Integer</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(String&nbsp;word:&nbsp;args)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callable</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Integer</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;callable&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;WordLengthCallable(word);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Future</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Integer</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;future&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;pool.submit(callable);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set.add(future);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;sum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(Future</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Integer</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;future&nbsp;:&nbsp;set)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;future.get();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">The&nbsp;sum&nbsp;of&nbsp;lengths&nbsp;is&nbsp;%s%n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;sum);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.exit(sum);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div><span style="font-size: 10pt;">
WordLengthCallable保存了每个词并使用该词的长度作为call方法的返回值。这个值可能会花点儿时间去生成，不过在这个例子中，可以立即知道它。 call方法的唯一要求是这个值要在call方法的结尾处返回。当Future的get方法稍后被调用时，如果任务运行得很快的话，Future将会自动得到这个值(如同本例的情况)，否则将一直等到该值生成完毕为止。多次调用get方法不会导致任务从该线程返回。因为该程序的目的是计划所有字的长度之和，它不会强令Callable任务结束。如果最后一个任务在前三个任务之前完成，也是没错的。对Future的get方法的第一次调用将只会等待Set中第一个任务结束，而不会阻塞其它的任务分别执行完毕。它只会等待当次线程或任务结束。这个特定的例子使用固定数线程池来产生ExecutorService对象，但其它有效的方法也是可行的。<br />
&nbsp;&nbsp;&nbsp; 关于执行器和线程池用法的更多信息，请见Java Tutorial中<a href="http://java.sun.com/tutorial/essential/concurrency/executors.html">Executors</a>一节。SwingWorker类是另一个使用Future的Runnable对象的例子，尽管有些微不同之处。更多信息请见Java Tutorial中<a href="http://java.sun.com/docs/books/tutorial/uiswing/concurrency/worker.html">Worker Threads and SwingWorker</a>一节。<br />
<br />
</span><img src ="http://www.blogjava.net/jiangshachina/aggbug/204007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2008-05-31 22:24 <a href="http://www.blogjava.net/jiangshachina/archive/2008/05/31/204007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串排序(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/04/07/190912.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Mon, 07 Apr 2008 01:10:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/04/07/190912.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/190912.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/04/07/190912.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/190912.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/190912.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 14pt;">字符串排序</span></strong><br />
</div>
<span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 本文是Sun官方以Blog形式发布的Java核心技术窍门(<a href="http://blogs.sun.com/CoreJavaTechTips/">JavaCoreTechTip</a>)中的一个。我之前尚未关注过java.text.Collator类，看过<a href="http://blogs.sun.com/CoreJavaTechTips/entry/sorting_strings"><span style="font-size: 10pt;">Sorting Strings</span></a></span><span style="font-size: 10pt;">这个tip之后觉得有些意义，故翻译在了此处，也希望对其它朋友有所助益。(2008.04.07最后更新)</span><br />
<br />
&nbsp;&nbsp;&nbsp; <span style="font-size: 10pt;">使用Java平台进行字符串排序被认为是一件简单的工作，但为国际市场开发程序时，则需要有更多的考虑。如果你陷入只关注英语的心态中，并认为你的程序会工作的很好，因为它所显示的字符串从今往后都是一样的，你可能认为一切都很正常。但一旦你有一位西班牙用户，他希望能够正常地对ma&#241;ana进行排序，但如果你都是使用String类中缺省的compare方法去做排序，字符&#241;将会跟在字符z之后，而在正常的西班牙语排序中，&#241;应该在字符n和o之间。这就是java.text包的类Collator发挥作用的地方了。
<br />
想像这样的一组词
<ul>
    <li> first
    </li>
    <li> ma&#241;ana
    </li>
    <li> man
    </li>
    <li> many
    </li>
    <li> maxi
    </li>
    <li> next
    </li>
</ul>
使用String类的默认排序机制，即它的compare()方法，排序的结果将会是：
<ul>
    <li> first
    </li>
    <li> man
    </li>
    <li> many
    </li>
    <li> maxi
    </li>
    <li> ma&#241;ana
    </li>
    <li> next
    </li>
</ul>
&nbsp;&nbsp;&nbsp; 此处，ma&#241;ana出现在maxi与next之间。而在西班牙语世界中，ma&#241;ana应该出现在many和maxi之间，
因为在字母表中，字符&#241;(读作e&#241;e)跟在n之后。当来了一个德语用户，想用他们自己的变音符时，你就可以写一个自己的定制排序规则来处理&#241;，
否则一组使用fa&#231;ade的设计模式将会怎样呢？你是否想让fa&#231;ade出现在factory之前或之后呢？(关键是如同对c或其它字符那样去处理&#231;的小写变音符。)
<br />
&nbsp;&nbsp;&nbsp; 这就是类Collator能派上用场的地方了。类Collator用于对语言敏感的排序问题，并不会只基于它们的ASCII/Unicode字符去尝试排序。
使用Collator要求你在完全应用它的特性之前要理解一个额外的属性，即称之为强度(Strength)的属性。Collator的强度设置决定了在排序时如何使用强(或弱)匹配。
该属性有4个可能的值：PRIMARY，SECONDARY，TERTIARY和IDENTICAL。具体是哪个强度在产生作用取决于语言环境。
典型地，会有如下的情况。按从后往前的顺序，IDENTICAL强度表示能够被进行相同的处理的字符必须是一致的。TERTIARY通常用于忽略大小写差异。SECONDARY用于忽略变音符，如n和&#241;。
PRIMARY与IDENTICAL相似也是基于字母之间差异，但是当处理控制字符和发音时还是有所不同。查看<code>Collator</code>的javadoc，
以获取更多关于这些强度之间的差异及分解(Decomposition)模式规则的信息。
<br />
&nbsp;&nbsp;&nbsp; 为了使用Collator，你需要先得到它的一个实例。你既可以调用getInstance方法以得到一个针对默认语言环境的Collator对象，
也可以传递一个指定的Locale对象给getInstance方法以得到一个针对特定语言环境的Collator对象。例如，为了获得针对一个西班牙语的
Collator对象，你应使用new Locale("es")去创建一个西班牙语的Locale对象，然后将它传入getInstance方法中：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">Collator&nbsp;esCollator&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;Collator.getInstance(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Locale(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">es</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));</span></div>
<span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 假设针对该语言环境的默认Collator强度，针对西班牙语的默认强度是SECONDARY已经足够了。然后你将这个Collator对象如任一Comparator对象
那样传入Collections类的sort方法的比较规则参数中，以得到排序后的List对象。<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">Collections.sort(list,&nbsp;esCollator);</span></div>
<span style="font-size: 10pt;">操作之前的单词列表，你现在就会得到一个基于西班牙语字母表的恰当排序结果：
<ul>
    <li> first
    </li>
    <li> man
    </li>
    <li> many
    </li>
    <li> ma&#241;ana
    </li>
    <li> maxi
    </li>
    <li> next
    </li>
</ul>
如果你在上述Collator中换用US的Locale对象，由于&#241;并不是US中本有的字母，所以ma&#241;ana将会出现在man和many之间。
<br />
这儿有一个简洁的例子以显示这些差异。
import java.awt.*;<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.text.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.List;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;Explicit&nbsp;import&nbsp;required</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;javax.swing.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;Sort&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;main(String&nbsp;args[])&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Runnable&nbsp;runner&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Runnable()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;run()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;words[]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;{</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">first</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ma&#241;ana</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">man</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">many</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">maxi</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">next</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Arrays.asList(words);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JFrame&nbsp;frame&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JFrame(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Sorting</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frame.setDefaultCloseOperation&nbsp;(JFrame.EXIT_ON_CLOSE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Box&nbsp;box&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Box.createVerticalBox();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frame.setContentPane(box);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JLabel&nbsp;label&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JLabel(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Word&nbsp;List:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;box.add(label);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JTextArea&nbsp;textArea&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JTextArea(&nbsp;list.toString());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;box.add(textArea);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collections.sort(list);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JLabel(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Sorted&nbsp;Word&nbsp;List:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;box.add(label);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textArea&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JTextArea(list.toString&nbsp;());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;box.add(textArea);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collator&nbsp;esCollator&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Collator.getInstance(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Locale(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">es</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collections.sort(list,&nbsp;esCollator);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JLabel(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Collated&nbsp;Word&nbsp;List:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;box.add(label);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textArea&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JTextArea(list.toString());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;box.add(textArea);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frame.setSize(</span><span style="color: rgb(0, 0, 0);">400</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">200</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frame.setVisible(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&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;&nbsp;EventQueue.invokeLater&nbsp;(runner);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<span style="font-size: 10pt;"><string></string><br />
<center>
<img src="http://blogs.sun.com/CoreJavaTechTips/resource/sorting.png" alt="" />
</center>&nbsp;&nbsp;&nbsp; 最后还有一点儿关于语言排序规则的信息。通过调用getInstance方法而得到的Collator对象通常是支持特定语言的RuleBasedCollator实例。
你可使用RuleBasedCollator去定义你自己的排序顺序。该类的Javadoc更完整地描述了这种规则的语法，但还是让我们先假设你有一个4字符字母表，
并希望字母的顺序是CAFE，而不是ACEF，你的规则看起来就像这样：</span><br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">String&nbsp;rule&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&nbsp;c,&nbsp;C&nbsp;&lt;&nbsp;a,&nbsp;A&nbsp;&lt;&nbsp;f,&nbsp;F&nbsp;&lt;&nbsp;e,&nbsp;E</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />
RuleBasedCollator&nbsp;collator&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;RuleBasedCollator(rule);</span></div>
&nbsp;&nbsp;&nbsp; <span style="font-size: 10pt;">上述规则通过展示不同字母的大小写定义了特定的字母顺序为cafe。现在对单词列表ace，cafe，ef和face使用新的规则进行排序，
排序结果的顺序为cafe，ace，face和ef：<string><br />
</string>
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.text.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;Rule&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;main(String&nbsp;args[])&nbsp;</span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);">&nbsp;ParseException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;words[]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;{</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">cafe</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ef</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">face</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;rule&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&nbsp;c,&nbsp;C&nbsp;&lt;&nbsp;a,&nbsp;A&nbsp;&lt;&nbsp;f,&nbsp;F&nbsp;&lt;&nbsp;e,&nbsp;E</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RuleBasedCollator&nbsp;collator&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;RuleBasedCollator(rule);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Arrays.asList(words);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collections.sort(list,&nbsp;collator);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(list);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<span style="font-size: 10pt;">在对上述代码编译并运行之后，你将看到使用新规则排序后的单词：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&gt;&nbsp;javac&nbsp;Rule.java<br />
&gt;&nbsp;java&nbsp;Rule<br />
</span><span style="color: rgb(128, 0, 0); font-weight: bold;">[</span><span style="color: rgb(128, 0, 0);">cafe,&nbsp;ace,&nbsp;face,&nbsp;ef</span><span style="color: rgb(128, 0, 0); font-weight: bold;">]</span></div>
<span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">请以后阅读Javadoc中更多的关于
规则语法的信息，再尝试扩展字母表并处理不同的变音符。<br />
&nbsp;&nbsp;&nbsp; 现在，当你为全世界开发
程序时，你的程序就能做出更好的准备以去适应本地用户了。也要确保字符串在资源包中，如之前的一个窍门所展示的那样：<span style="font-size: 10pt;">Earlier tip。(译注：原文并没有提供这个Earlier tip的正确链接地址。)</span></span>
<img src ="http://www.blogjava.net/jiangshachina/aggbug/190912.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2008-04-07 09:10 <a href="http://www.blogjava.net/jiangshachina/archive/2008/04/07/190912.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>