﻿<?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-faintbear-随笔分类-JAVA</title><link>http://www.blogjava.net/faintbear/category/703.html</link><description>小风嗖嗖的刮着......</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 13:15:06 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 13:15:06 GMT</pubDate><ttl>60</ttl><item><title>MIDP2.0及其移植技术分析(转)</title><link>http://www.blogjava.net/faintbear/archive/2006/07/12/57798.html</link><dc:creator>小力力力</dc:creator><author>小力力力</author><pubDate>Wed, 12 Jul 2006 06:32:00 GMT</pubDate><guid>http://www.blogjava.net/faintbear/archive/2006/07/12/57798.html</guid><wfw:comment>http://www.blogjava.net/faintbear/comments/57798.html</wfw:comment><comments>http://www.blogjava.net/faintbear/archive/2006/07/12/57798.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/faintbear/comments/commentRss/57798.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/faintbear/services/trackbacks/57798.html</trackback:ping><description><![CDATA[
		<p>
				<b>摘要：</b>MIDP即移动信息设备规范，是专门基于资源和网络连接有限的移动设备之上的J2ME应用规范。本文在分析MIDP2.0的基础上，详细阐述MIDP的事件处理、文件系统、用户图形接口和网络等主要部分在不同平台间移植的实现过程。 
</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">    <b>关键词：</b></span>J2ME MIDP 移植 平台无关 本地代码</p>
		<p style="TEXT-INDENT: 0px">
				<b>1 MIDP2.0简介</b>
		</p>
		<p style="TEXT-INDENT: 30px">随着现代信息化社会的发展，小型移动通信设备已经从最初的一种单纯的通信工具转变成如今集通信、工作、娱乐等功能为一体的综合设备；但仅有这些还不能满足用户的要求。个性永远是千变万化的，时尚也不会始终为一种模式。因此，在移动终端上开发通用的、丰富的应用已成为必然的趋势。这些应用可以按用户的意愿随时安装和删除。</p>
		<p style="TEXT-INDENT: 30px">J2ME（JAVA2 Micro Edition）正是这样一种JAVA应用开发平台。实际上，JAVA语言从其诞生起就以其运行的平台无关性这一强大的优势而成为网络应用的宠儿。J2ME是JAVA2标准版本的微型版本，专门为小型移动设备所设计。这些设备处理器的处理能力都不强，可使用的资源也有限。因此，J2ME只包含了J2SE中在移动通信设备上所必需的功能和组件，使其能够在移动设备及其有限的资源上开发出丰富多彩且平台无关的应用。J2ME在结构上分为CDC（Connecte Device Configuration）和基于其上，以Foundation Profile为主的规范，以及CLDC（Connecte Limited Device Configuration）和基于其上，以MIDP为主的规范。</p>
		<p style="TEXT-INDENT: 30px">MIDP（Mobile Information Device Profile）是移信息设备规范的简称。规范具体定义了J2ME适用的硬件和软件框架，并提供了这个框架要实现的基本功能及其标准接口；而应用开发者就可以基于这个框架开发出各种应用。2000年9月，SUN公司发布了MIDP的第一个正式版本MIDP1.0。它将J2ME适用的设备定位在至少拥有数百KB RAM和ROM，并具有基本网络和显示功能的移动通信设备上；在该基础上定义了一系列软件接的移动通信设备上；在该上基础上定义了一系列软件接口，其中包括基本输入输出、图形化用户接口（GUI）、网络、事件机制、文件系统、应用管理系统（AMS）等之后，随着JAVA技术的不断发展和用户需求的不断提高，SUN公司又于2002年11月发布了MIDP2.0。它对设备的内存资源和处理能力的要求较1.0要高，但MIDP2.0也为应用开发者提供了更方便、更丰富多彩的软件包，主要增加了游戏接口的实现、声音输出接口的实现安全网络机制的实现。MIDP2.0的这些特性将使基于移动设备的JAVA应用具有更加广阔的前景，也必将使新一代的移动设备发生革命性的变化并领导时尚潮流。MIDP2.0接口包如表1所列。<br /><br /><b>表1 MIDP2.0接口包及其功能</b></p>
		<table bordercolordark="#ffffff" width="100%" bordercolorlight="#000000" border="1">
				<tbody>
						<tr class="main">
								<td align="middle" width="45%">包</td>
								<td align="middle" width="55%">功      能</td>
						</tr>
						<tr class="main">
								<td width="45%">javax.microedition.lcdui</td>
								<td align="middle" width="55%">提供一系列用户界面接口</td>
						</tr>
						<tr class="main">
								<td width="45%">javax.microedition.lcdui.game</td>
								<td align="middle" width="55%">专门用于游戏设计的接口</td>
						</tr>
						<tr class="main">
								<td width="45%">javax.microedition.rms</td>
								<td align="middle" width="55%">数据管理，用于保存数据记录</td>
						</tr>
						<tr class="main">
								<td width="45%">javax.microedition.midlet</td>
								<td align="middle" width="55%">JAVA应用管理接口</td>
						</tr>
						<tr class="main">
								<td width="45%">javax.microedition.io</td>
								<td align="middle" width="55%">基本网络连接接口</td>
						</tr>
						<tr class="main">
								<td width="45%">javax.microedition.media</td>
								<td align="middle" width="55%">媒体接口规范（JSR-135）的实现包</td>
						</tr>
						<tr class="main">
								<td width="45%">javax.microedition.media.control</td>
								<td align="middle" width="55%">媒体播放器的控制类</td>
						</tr>
						<tr class="main">
								<td width="45%">javax.microedition.pki</td>
								<td align="middle" width="55%">数字签名规范的实现接口（用于安全网络）</td>
						</tr>
						<tr class="main">
								<td width="45%">java.io</td>
								<td align="middle" width="55%">JAVA基本输入输出接口</td>
						</tr>
						<tr class="main">
								<td width="45%">java.lang</td>
								<td align="middle" width="55%">JAVA基本数据类型接口</td>
						</tr>
						<tr class="main">
								<td width="45%">java.util</td>
								<td align="middle" width="55%">JAVA基本应用接口</td>
						</tr>
				</tbody>
		</table>
		<p style="TEXT-INDENT: 0px">
				<b>2 MIDP2.0的移植</b>
		</p>
		<p style="TEXT-INDENT: 30px">既然MIDP2.0是定位在移动通信设备之上的一系列JAVA应用开发接口，我们就必须考虑如何将整个MIDP系统嵌入到特定的硬件设备和其上的操作系统中。只有这样，JAVA应用程序才能运行在该设备上，并利用MIDP提供的强大功能将用户带入一个全新的JAVA世界。在一个完全不同的操作系统平台上，用该平台上对应的系统API调用（或一系列操作），替换MIDP参考实现中所有与操作平台相关的调用（或操作），使MIDP能在目标平台上正确地执行所有要求的功能；同时，调用该平台上特有的能充分发挥目标设备硬件特性的接口，替换参考实现中相应的接口，使MIDP能在目标平台上更高效地运行，这个过程就称为MIDP的移植。</p>
		<p style="TEXT-INDENT: 30px">MIDP由许多不同的部分组成，每一部分完成MIDP一个特定的功能接口。其中需要移植的部分主要包括事件处理、文件系统、用户图形化接口、网络、AMS、多媒体。它们都分为高端的JAVA层和低端的本地方法层。JAVA层是用JAVA语言实现的，由KVM解释执行；因此没有涉及到与操作系统平台相关的调用和操作，可以不经修改就在任何操作平台上运行，是平台无关的（PlateForm Independent）。它的移植主要是为满足用户的特殊要求而进行的个性化工作。本地方法层（NativeCode）是指为提高代码的执行效率，保持JAVA语言的平台无关性而使用C语言实现的部分MIDP功能的代码。本地即是指它是与当前的操作平台相关的，它的移植才是涉及到具体平台和执行效率而进行的具体调用和操作的替换过程，其结构如图1所示。</p>
		<p style="TEXT-INDENT: 30px">下面，我们就具体到MIDP的每一个部分的移植进行讨论。</p>
		<p style="TEXT-INDENT: 30px">2.1 事件处理</p>
		<p style="TEXT-INDENT: 30px">MIDP的事件处理部分要处理的事件主要来自两个方面：①来自虚拟机底层的事件，如虚拟机的异常消息；②来自MIDP内部的事件，如屏幕刷新、按键消息、触控笔点击消息、时钟消息等。由于不同的平台可能使用不同的事件消息获取和传递机制，因此MIDP事件处理的移植也集中在这上面，其实现被放在本地方法层的文件nativeGUI.c中的函数GetAndStoreKVMEvent中。我们只需根据目标平台获取和传递事件的要求修改该文件中的相应函数即可。</p>
		<p style="TEXT-INDENT: 30px">例如，Windows采用消息响应机制来处理各种事件，所有消息都可以通过系统API调用GetMessage获取，系统会调用消息处理函数WndProc(HWND hwnd、UINTiMsg、WPARAM wParam、LRARAM 1Param)，在其中处理和传递不同的事件。其大致实现过程如下：</p>
		<p style="TEXT-INDENT: 30px">void</p>
		<p style="TEXT-INDENT: 30px">GetAndStoreNextKVMEvent(bool_t forever,ulong64 waitUntil){</p>
		<p style="TEXT-INDENT: 30px">MSG msg；</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">while(GetMessage(&amp;msg,NULL,0,0)){</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">TranslateMessage(&amp;msg);</p>
		<p style="TEXT-INDENT: 30px">DispatchMessage(&amp;msg);</p>
		<p style="TEXT-INDENT: 30px">if(gotEvent){</p>
		<p style="TEXT-INDENT: 30px">StoreMIDPEvent(&amp;kvmEvent);</p>
		<p style="TEXT-INDENT: 30px">Return;</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">return;</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">static LRESULT CALLBACK</p>
		<p style="TEXT-INDENT: 30px">WndProc (HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam){</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">switch(iMsg){</p>
		<p style="TEXT-INDENT: 30px">case WM_CREATE:</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">case WM_KEYDOWN:</p>
		<p style="TEXT-INDENT: 30px">case WM_KEYUP:</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">MIDP在GetAndStoreNextKVMEvent中获取事件后，就完全独立地传递和处理事件消息，与平台无关，因此无需移植。<br /><img height="249" hspace="10" src="http://www.embed-dsp.com/Files/image/2006-4/18/0641822021626193.gif" width="549" vspace="10" border="0" /><br /><font size="3">    </font><span class="main1">2.2 文件系统</span></p>
		<p style="TEXT-INDENT: 30px">基于MIDP的JAVA应用以及MIDP本身在某些时候要求数据能够长期保存，即使在应用退出或系统掉电的情况下，数据也不能丢失。这就必须借助于MIDP的文件系统。MIDP的文件系统同样分为JAVA层（称为RMS，即Record Manage System）和本地方法层。一般情况下，文件系统的JAVA层不用移植就可以在任何平台上运行，但如果目标平台的文件系统较为特殊，例如采用数据库的记录方式保存数据，甚至根本就没有提供高效的数据存取接口，我们就必须自己实现数据存取接口。这样，JAVA层就需要跳过RMS而直接通过本地方法调用本地接口，相应的RMS的JAVA代码就可以从MIDP中删去。</p>
		<p style="TEXT-INDENT: 30px">而在文件系统的本地方法层，MIDP会调用目标平台的数据存取接口来实现MIDP本身的数据存取。这些接口是平台相关的，是文件系统中需要移植的部分。这些调用被放在文件src/share/native/storage.c中，主要包括文件的打开（open）、文件的关闭（close）、文件的读写（read、write）、文件属性的获取（size、freesize等）、文件的删除（delete）、文件的定位（seek）、文件的删节（truncate）等。以下便是MIDP文件系统在Windows下的部分实现。</p>
		<p style="TEXT-INDENT: 30px">文件的打开：</p>
		<p style="TEXT-INDENT: 30px">int storageOpen(char**ppszError,char*pszAsciiFilename,int ioMode){</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">handle=open(pszAsciiFilename,flags,creationMode)；</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">文件的关闭：</p>
		<p style="TEXT-INDENT: 30px">void storageClose(char**ppszError,int handle){</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">status=close(handle)；</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">文件的读取：</p>
		<p style="TEXT-INDENT: 30px">int storageRead(char**ppszError,int handle,char*buffer,int length)</p>
		<p style="TEXT-INDENT: 30px">{</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">bytesRead=read(handle,buffer,length);</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">文件的写入：</p>
		<p style="TEXT-INDENT: 30px">void storageWrite(char**ppszError,int handle,char*buffer,int length){</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">bytesWritten=write(handle,buffer,length);</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">还有许多其它有关文件的操作，移植时只需使用目标平台的API替换以上的Widnows调用，这里就不再逐一列举。</p>
		<p style="TEXT-INDENT: 30px">2.3 用户图形化接口</p>
		<p style="TEXT-INDENT: 30px">用户图形化接口包括画点、画线、作圆、作椭圆、位图拷贝等基本作图函数（可在GRAPHICS.C中找到）；有关定时器、屏幕刷新和键盘触控笔消息等有关与用户交互的操作（可在TEXT.C中找到），它是整个MIDP移植中工作量最大，也是对上层应用的执行效率影响最大的一个部分。这是因为用户在应用中看到的各种图形和文字都是调用底层的图形函数在屏幕上作图的结果。由于屏幕要频繁刷新，图形函数也就成为应用调用最多的接口。因此，移植者必须使每一个底层作图函数与硬件设备紧密配合起来，并使用最高效的算法。</p>
		<p style="TEXT-INDENT: 30px">在不同的平台上，能最大地发挥其作图功能的函数和算法不尽相，这就要求移植者作大量细致的工作，按照MIDP规范的要求逐一重新实现每一个作图函数和屏幕刷新函 数。下面我们就以将画线函数和位图拷贝函数在Windows上的实现为例，简单说明移植要做的工作（键盘、触控笔是以事件消息的方式实现的，它们的移植与事件消息的移植相同）。</p>
		<p style="TEXT-INDENT: 30px">Windows的画线函数接口：</p>
		<p style="TEXT-INDENT: 30px">Void LCDUIdrawLine(int pixel,short*clip,void*dst,int dotted,int x1,int y1,int x2,int y2){</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">Polyline(hdc,pts,2);/*绘x1,y1点像素信号*/</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">Windwos的屏幕刷新函数：</p>
		<p style="TEXT-INDENT: 30px">Void refreshPaintWindow(int x1,int y1,int x2,int y2){</p>
		<p style="TEXT-INDENT: 30px">RECT r；</p>
		<p style="TEXT-INDENT: 30px">If(x1&lt;x2){</p>
		<p style="TEXT-INDENT: 30px">r.left=x1+x_offset;r.right=x2+x_offset;</p>
		<p style="TEXT-INDENT: 30px">}else{</p>
		<p style="TEXT-INDENT: 30px">r.left=x2+x_offset;r.right=x1+x_offset;</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">if(y1&lt;y2){</p>
		<p style="TEXT-INDENT: 30px">r.top=y1+y_offset;r.bottom=y2+y_offset;</p>
		<p style="TEXT-INDENT: 30px">}else{</p>
		<p style="TEXT-INDENT: 30px">r.top=y2+y_offset;r.bottom=y1+y_offset；</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">++r.bottom;++r.right;</p>
		<p style="TEXT-INDENT: 30px">InvalidateRect(hMainWindow,&amp;r,KNI_TRUE);</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">如果目标平台对这些GUI接口函数有不同实现法，可以用这些方法替换以上的Windows系统调用，这样才能使MIDP图形化用户接口正确地工作，并充分发挥目标平台的工作效率。</p>
		<p style="TEXT-INDENT: 30px">2.4 网络</p>
		<p style="TEXT-INDENT: 30px">MIDP的网络功能是指基于MIDP的J2ME应用可以通过HTTP等网络协议进行下载安装，不同的MIDlet实体也可以通过它交换信息，实现资源共享。遵循HTTP协议的规定，移植者必须利用目标平台的底层网络接口重新实现网络的初始化（networkInit）、建立连接（open0）、断开连接（close0）、接收数据（read0）、获取缓冲区的剩余空间（available0）、关闭发送（shutdownOutput）。如果目标设备具有服务器功能，还要实现serversocket所有上述功能。所有上述接口都在文件socketProtocol_md.c中实现。</p>
		<p style="TEXT-INDENT: 30px">Windwos中获取IP地址的实现：</p>
		<p style="TEXT-INDENT: 30px">Int prim_com_sun_midp_io_j2me_socket_Protocol_getIpNumber</p>
		<p style="TEXT-INDENT: 30px">(char*host)</p>
		<p style="TEXT-INDENT: 30px">{</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">hp=gethostbyname(host);</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">如果目标平台还需要其它网络协议（datagram、comm），其移植过程与Socket的移植基本相同。</p>
		<p style="TEXT-INDENT: 30px">2.5 应用管理系统（AMS）</p>
		<p style="TEXT-INDENT: 30px">MIDP的应用管理系统(application management system)负责管理当前设备中安装的J2ME应用，其功能包括MIDlet的加载、安装、显示、更新和删除。AMS从main.c中的函数main()开始执行，根据其输入初始化一些系统参数，包括系统路径（classJ2ME MIDP 移植 平台无关 本地代码）、堆空间大小（heapsize）、命令行（command line）等，然后就启动KVM，而KVM就会从AMS的JAVA界面main.java开始解释执行java代码。AMS的所有管理功能都是用JAVA语言实现的，因此AMS的实现是与平台无关的。但不同的平台可能有不同的系统参数和格式，对AMS的界面网络也可能有不同的要求。所以，移植者有可能要修改main.c中解析系统参数的部分，保证AMS能正确解析目标平台的所有参数；同时修改AMS的JAVA层，使其界面网络满足用户的需求。</p>
		<p style="TEXT-INDENT: 30px">2.6 多媒体</p>
		<p style="TEXT-INDENT: 30px">MIDP2.0较MIDP1.0最大的改变就是在MIDP2.0中向应用提供了音频接口（Audio API）的支持。音频接口是移动设备媒体接口MMAPI（Mobile Media API）的一部分。音频的播放过程为5个部分（unrealized、realized、prefetched、started、closed），同时它有自己的音频播放事件的传道和处理过程。MIDP音频播放部分所要做的移植工作就主要集中在声音播放接口，事件的处理方式和兼容不同的音频文件格式上。</p>
		<p style="TEXT-INDENT: 30px">播放接口的移植：不同的目标平台，提供的音频系统API是不同的，有的系统甚至根本没有提供播放音频的API。这时，移植者就要根据目标平台的实现情况替换或自己实现音频的播放接口。</p>
		<p style="TEXT-INDENT: 30px">Windows的音频播放接口（win32/native/MMATONE.C）：</p>
		<p style="TEXT-INDENT: 30px">Java_javax_microedition_media_Manager_nPlayTone(KNITRAPS)</p>
		<p style="TEXT-INDENT: 30px">{</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">chn1=getMidiChnl();</p>
		<p style="TEXT-INDENT: 30px">if(chnl==-1){</p>
		<p style="TEXT-INDENT: 30px">KNI_ReturnInt(0)；</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">tones[chn].msg=((note&amp;0xff)&lt;&lt;8)|0x00000090|(chnl&amp;0xf);</p>
		<p style="TEXT-INDENT: 30px">msg=((vol&amp;0xff)&lt;&lt;16)|((note&amp;0xff)&lt;&lt;8)|0x90|(chnl &amp;0xf);</p>
		<p style="TEXT-INDENT: 30px">midiOutShortMsg(midiOut,msg);</p>
		<p style="TEXT-INDENT: 30px">timerID=timeSetEvent(dur,TIMERES,(LPTIME CALLBACK)timeToneProc,(DWORD)chnl,TIME_ONESHOT);</p>
		<p style="TEXT-INDENT: 30px">tones[chnl].timerID=timerID;</p>
		<p style="TEXT-INDENT: 30px">……</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 30px">事件传递的移植：MIDP中音频播放结束的事件（EOM）是专门通过系统的消息机制传递，而不是通过MIDP的事件传递，因此也需要移植：</p>
		<p style="TEXT-INDENT: 30px">Windows---OM的传递（win32/native/MMAEVT.C）:void injectNativeEvent(int pID,int curMTime){</p>
		<p style="TEXT-INDENT: 30px">PostMessage(hMain Window,WM_APP,(WPARAM)(pID),(LPARAM)(curMTime));</p>
		<p style="TEXT-INDENT: 30px">return;</p>
		<p style="TEXT-INDENT: 30px">}</p>
		<p style="TEXT-INDENT: 0px">
				<b>3 总结</b>
		</p>
		<p style="TEXT-INDENT: 30px">综上所述，MID2.0的移植要以两个方面为出发点：①兼容性。移植后的MIDP实现必须能够在目标平台上正常运行，所有与目标平台不兼容的调用都必须替换为能完成相同功能且兼容的目标平台的系统调用或过程。②高效性。移植后的MIDP实现必须能充分发挥目标平台的效率和特性，用最小的代价完成MIDP的功能。另外，MIDP的移植还要分满足最终用户的个性化要求，为它们设计出丰富多彩的界面网络。 </p>
<img src ="http://www.blogjava.net/faintbear/aggbug/57798.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/faintbear/" target="_blank">小力力力</a> 2006-07-12 14:32 <a href="http://www.blogjava.net/faintbear/archive/2006/07/12/57798.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java性能的优化(转)</title><link>http://www.blogjava.net/faintbear/archive/2005/08/31/11615.html</link><dc:creator>小力力力</dc:creator><author>小力力力</author><pubDate>Wed, 31 Aug 2005 03:40:00 GMT</pubDate><guid>http://www.blogjava.net/faintbear/archive/2005/08/31/11615.html</guid><wfw:comment>http://www.blogjava.net/faintbear/comments/11615.html</wfw:comment><comments>http://www.blogjava.net/faintbear/archive/2005/08/31/11615.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/faintbear/comments/commentRss/11615.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/faintbear/services/trackbacks/11615.html</trackback:ping><description><![CDATA[<CENTER>
<H4><FONT size=2>Java性能的优化</FONT></H4></CENTER><BR><FONT size=2>(来源：http://www.ccw.com.cn) <BR><BR>Java在九十年代中期出现以后，在赢得赞叹的同时，也引来了一些批评。赢得的赞叹主要是Java的跨平台的操作性，即所谓的”Write Once,Run Anywhere”.但由于Java的性能和运行效率同C相比，仍然有很大的差距，从而引来了很多的批评。</FONT>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>对于服务器端的应用程序，由于不大涉及到界面设计和程序的频繁重启，Java的性能问题看似不大明显，从而一些Java的技术，如JSP,Servlet,EJB等在服务器端编程方面得到了很大的应用，但实际上，Java的性能问题在服务器端依然存在。下面我将分四个方面来讨论Java的性能和执行效率以及提高Java性能的一些方法。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>一．关于性能的基本知识</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>1．性能的定义</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>在我们讨论怎样提高Java的性能之前，我们需要明白“性能“的真正含义。我们一般定义如下五个方面作为评判性能的标准。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>1） 运算的性能----哪一个算法的执行性能最好</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>2） 内存的分配----程序需要分配多少内存，运行时的效率和性能最高。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>3） 启动的时间----程序启动需要多少时间。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>4） 程序的可伸缩性-----程序在用户负载过重的情况下的表现。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>5） 性能的认识------用户怎样才能认识到程序的性能。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>对于不同的应用程序，对性能的要求也不同。例如，大部分的应用程序在启动时需要较长的时间，从而对启动时间的要求有所降低；服务器端的应用程序通常都分配有较大的内存空间，所以对内存的要求也有所降低。但是，这并不是所这两方面的性能可以被忽略。其次，算法的性能对于那些把商务逻辑运用到事务性操作的应用程序来讲非常重要。总的来讲，对应用程序的要求将决定对各个性能的优先级。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>2．怎样才能提高JAVA的性能</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>提高JAVA的性能，一般考虑如下的四个主要方面：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>（1） 程序设计的方法和模式</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>一个良好的设计能提高程序的性能，这一点不仅适用于JAVA，也适用也任何的编程语言。因为它充分利用了各种资源，如内存，CPU,高速缓存，对象缓冲池及多线程，从而设计出高性能和可伸缩性强的系统。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>当然，为了提高程序的性能而改变原来的设计是比较困难的，但是，程序性能的重要性常常要高于设计上带来的变化。因此，在编程开始之前就应该有一个好的设计模型和方法。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>（2） JAVA布署的环境。</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>JAVA布署的环境就是指用来解释和执行JAVA字节码的技术，一般有如下五种。即解释指令技术(Interpreter Technology)，及时编译的技术(Just In Time Compilier Technology), 适应性优化技术（Adaptive Optimization Technology）, 动态优化，提前编译为机器码的技术（Dynamic Optimization,Ahead Of Time Technology）和编译为机器码的技术（Translator Technology）.</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>这些技术一般都通过优化线程模型，调整堆和栈的大小来优化JAVA的性能。在考虑提高JAVA的性能时，首先要找到影响JAVA性能的瓶颈（BottleNecks），在确认了设计的合理性后，应该调整JAVA布署的环境，通过改变一些参数来提高JAVA应用程序的性能。具体内容见第二节。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>（3） JAVA应用程序的实现</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>当讨论应用程序的性能问题时，大多数的程序员都会考虑程序的代码，这当然是对的，当更重要的是要找到影响程序性能的瓶颈代码。为了找到这些瓶颈代码，我们一般会使用一些辅助的工具，如Jprobe,Optimizit,Vtune以及一些分析的工具如TowerJ Performance等。这些辅助的工具能跟踪应用程序中执行每个函数或方法所消耗掉的时间，从而改善程序的性能。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>(4) 硬件和操作系统</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>为了提高JAVA应用程序的性能，而采用跟快的CPU和更多的内存，并认为这是提高程序性能的唯一方法，但事实并非如此。实践经验和事实证明，只有遭到了应用程序性能的瓶颈，从而采取适当得方法，如设计模式，布署的环境，操作系统的调整，才是最有效的。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>3．程序中通常的性能瓶颈。</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>所有的应用程序都存在性能瓶颈，为了提高应用程序的性能，就要尽可能的减少程序的瓶颈。以下是在JAVA程序中经常存在的性能瓶颈。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14>
<P align=center><FONT size=2><IMG src="http://www.huihoo.com/java/performance/i/01_7_9_3a.gif" border=0></FONT></P></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>了解了这些瓶颈后，就可以有针对性的减少这些瓶颈，从而提高JAVA应用程序的性能</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>4. 提高JAVA程序性能的步骤</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>为了提高JAVA程序的性能，需要遵循如下的六个步骤。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>a) 明确对性能的具体要求</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>在实施一个项目之前，必须要明确该项目对于程序性能的具体要求，如：这个应用程序要支持5000个并发的用户，并且响应时间要在5秒钟之内。但同时也要明白对于性能的要求不应该同对程序的其他要求冲突。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>b) 了解当前程序的性能</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>你应该了解你的应用程序的性能同项目所要求性能之间的差距。通常的指标是单位时间内的处理数和响应时间，有时还会比较CPU和内存的利用率。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>c) 找到程序的性能瓶颈</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>为了发现程序中的性能瓶颈，通常会使用一些分析工具，如：TowerJ Application Performance Analyzer或VTune来察看和分析程序堆栈中各个元素的消耗时间，从而正确的找到并改正引起性能降低的瓶颈代码，从而提高程序的性能。这些工具还能发现诸如过多的异常处理，垃圾回收等潜在的问题。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>d) 采取适当的措施来提高性能</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>找到了引起程序性能降低的瓶颈代码后，我们就可以用前面介绍过的提高性能的四个方面，即设计模式，JAVA代码的实现，布署JAVA的环境和操作系统来提高应用程序的性能。具体内容将在下面的内容中作详细说明。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>e) 只进行某一方面的修改来提高性能</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>一次只改变可能引起性能降低的某一方面，然后观察程序的性能是否有所提高，而不应该一次改变多个方面，因为这样你将不知道到底哪个方面的改变提高了程序的性能，哪个方面没有，即不能知道程序瓶颈在哪。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><I><FONT size=2>f) 返回到步骤c,继续作类似的工作，一直达到要求的性能为止。</FONT></I></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2></FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>二． JAVA布署的环境和编译技术</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　开发JAVA应用程序时，首先把JAVA的源程序编译为与平台无关的字节码。这些字节码就可以被各种基于JVM的技术所执行。这些技术主要分为两个大类。即基于解释的技术和基于提前编译为本地码的技术。其示意图如下：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14>
<P align=center><FONT size=2><IMG src="http://www.huihoo.com/java/performance/i/01_7_9_3b.gif" border=0></FONT></P></TD></TR>
<TR>
<TD class=a14><FONT size=2>具体可分为如下的五类：　　</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>a) 解释指令技术</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>其结构图和执行过程如下：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14>
<P align=center><FONT size=2><IMG src="http://www.huihoo.com/java/performance/i/01_7_9_3c.gif" border=0> </FONT></P></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　JAVA的编译器首先把JAVA源文件编译为字节码。这些字节码对于JAVA虚拟机(JVM)来讲就是机器的指令码。然后，JAVA的解释器不断的循环取出字节码进行解释并执行。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　这样做的优点是可以实现JAVA语言的跨平台，同时生成的字节码也比较紧凑。JAVA的一些优点，如安全性，动态性都得保持；但缺点是省生成的字节码没有经过什么优化，同全部编译好的本地码相比，速度比较慢。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>b) 及时编译技术（Just In Time）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　　及时编译技术是为了解决指令解释技术效率比较低，速度比较慢的情况下提出的，其结构图如下所示。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14>
<P align=center><FONT size=2><IMG src="http://www.huihoo.com/java/performance/i/01_7_9_3d.gif" border=0> </FONT></P></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>其主要变化是在JAVA程序执行之前，又JIT编译器把JAVA的字节码编译为机器码。从而在程序运行时直接执行机器码，而不用对字节码进行解释。同时对代码也进行了部分的优化。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>这样做的优点是大大提高了JAVA程序的性能。同时，由于编译的结果并不在程序运行间保存，因此也节约了存储空间了加载程序的时间；缺点是由于JIT编译器对所有的代码都想优化，因此也浪费了很多的时间。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>IBM和SUN公司都提供了相关的JIT产品。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>c) 适应性优化技术（Adaptive Optimization Technology）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>同JIT技术相比，适应性优化技术并不对所有的字节码进行优化。它会跟踪程序运行的成个过程，从而发现需要优化的代码，对代码进行动态的优化。对优化的代码，采取80/20的策略。从理论上讲，程序运行的时间越长，代码就越优化。其结构图如下：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14>
<P align=center><FONT size=2><IMG src="http://www.huihoo.com/java/performance/i/01_7_9_3e.gif" border=0> </FONT></P></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>其优点是适应性优化技术充分利用了程序执行时的信息，发行程序的性能瓶颈，从而提高程序的性能；其缺点是在进行优化时可能会选择不当，发而降低了程序的性能。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>其主要产品又IBM,SUN的HotSpot.</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>d) 动态优化，提前编译为机器码的技术（Dynamic Optimization,Ahead Of Time）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>动态优化技术充分利用了JAVA源码编译，字节码编译，动态编译和静态编译的技术。其输入时JAVA的原码或字节码，而输出是经过高度优化的可执行代码和个来动态库的混合(Window中是DLL文件，UNIX中是共享库.a .so文件)。其结构如下：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14>
<P align=center><FONT size=2><IMG src="http://www.huihoo.com/java/performance/i/01_7_9_3f.gif" border=0> </FONT></P></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>其优点是能大大提高程序的性能；缺点是破坏了JAVA的可移植性，也对JAVA的安全带来了一定的隐患。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>其主要产品是TowerJ3.0. <BR><BR>三．优化JAVA程序设计和编码，提高JAVA程序性能的一些方法。</FONT></B></FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>通过使用一些前面介绍过的辅助性工具来找到程序中的瓶颈，然后就可以对瓶颈部分的代码进行优化。一般有两种方案：即优化代码或更改设计方法。我们一般会选择后者，因为不去调用以下代码要比调用一些优化的代码更能提高程序的性能。而一个设计良好的程序能够精简代码，从而提高性能。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>下面将提供一些在JAVA程序的设计和编码中，为了能够提高JAVA程序的性能，而经常采用的一些方法和技巧。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>1．对象的生成和大小的调整。</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>JAVA程序设计中一个普遍的问题就是没有好好的利用JAVA语言本身提供的函数，从而常常会生成大量的对象（或实例）。由于系统不仅要花时间生成对象，以后可能还需花时间对这些对象进行垃圾回收和处理。因此，生成过多的对象将会给程序的性能带来很大的影响。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>例1：关于String ,StringBuffer，+和append</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>JAVA语言提供了对于String类型变量的操作。但如果使用不当，会给程序的性能带来影响。如下面的语句：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>String name=new String(“HuangWeiFeng”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.out.println(name+”is my name”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>看似已经很精简了，其实并非如此。为了生成二进制的代码，要进行如下的步骤和操作。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（1） 生成新的字符串 new String(STR_1);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（2） 复制该字符串。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（3） 加载字符串常量”HuangWeiFeng”(STR_2);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（4） 调用字符串的构架器（Constructor）;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（5） 保存该字符串到数组中（从位置0开始）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（6） 从java.io.PrintStream类中得到静态的out变量</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（7） 生成新的字符串缓冲变量new StringBuffer(STR_BUF_1);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（8） 复制该字符串缓冲变量</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（9） 调用字符串缓冲的构架器（Constructor）;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（10） 保存该字符串缓冲到数组中（从位置1开始）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（11） 以STR_1为参数，调用字符串缓冲(StringBuffer)类中的append方法。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（12） 加载字符串常量”is my name”(STR_3);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（13） 以STR_3为参数，调用字符串缓冲(StringBuffer)类中的append方法。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（14） 对于STR_BUF_1执行toString命令。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（15） 调用out变量中的println方法，输出结果。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>由此可以看出，这两行简单的代码，就生成了STR_1,STR_2,STR_3,STR_4和STR_BUF_1五个对象变量。这些生成的类的实例一般都存放在堆中。堆要对所有类的超类，类的实例进行初始化，同时还要调用类极其每个超类的构架器。而这些操作都是非常消耗系统资源的。因此，对对象的生成进行限制，是完全有必要的。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>经修改，上面的代码可以用如下的代码来替换。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>StringBuffer name=new StringBuffer(“HuangWeiFeng”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.out.println(name.append(“is my name.”).toString());</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>系统将进行如下的操作。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(1) 生成新的字符串缓冲变量new StringBuffer(STR_BUF_1);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(2) 复制该字符串缓冲变量</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(3) 加载字符串常量”HuangWeiFeng”(STR_1);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(4) 调用字符串缓冲的构架器（Constructor）;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(5) 保存该字符串缓冲到数组中（从位置1开始）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(6) 从java.io.PrintStream类中得到静态的out变量</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(7) 加载STR_BUF_1;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(8) 加载字符串常量”is my name”(STR_2);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(9) 以STR_2为参数，调用字符串缓冲(StringBuffer)实例中的append方法。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(10) 对于STR_BUF_1执行toString命令。(STR_3)</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(11)调用out变量中的println方法，输出结果。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>由此可以看出，经过改进后的代码只生成了四个对象变量：STR_1,STR_2,STR_3和STR_BUF_1.你可能觉得少生成一个对象不会对程序的性能有很大的提高。但下面的代码段2的执行速度将是代码段1的2倍。因为代码段1生成了八个对象，而代码段2只生成了四个对象。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>代码段1：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>String name= new StringBuffer(“HuangWeiFeng”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>name+=”is my”;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>name+=”name”;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>代码段2：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>StringBuffer name=new StringBuffer(“HuangWeiFeng”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>name.append(“is my”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>name.append(“name.”).toString();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>因此，充分的利用JAVA提供的库函数来优化程序，对提高JAVA程序的性能时非常重要的.其注意点主要有如下几方面；</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（1） 尽可能的使用静态变量（Static Class Variables）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>如果类中的变量不会随他的实例而变化，就可以定义为静态变量，从而使他所有的实例都共享这个变量。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>例：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public class foo</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>SomeObject so=new SomeObject();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>就可以定义为：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public class foo</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>static SomeObject so=new SomeObject();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>} </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（2） 不要对已生成的对象作过多的改变。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>对于一些类(如：String类)来讲，宁愿在重新生成一个新的对象实例，而不应该修改已经生成的对象实例。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>例：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>String name=”Huang”;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>name=”Wei”;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>name=”Feng”;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>上述代码生成了三个String类型的对象实例。而前两个马上就需要系统进行垃圾回收处理。如果要对字符串进行连接的操作，性能将得更差。因为系统将不得为此生成更多得临时变量。如上例1所示。 </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（3） 生成对象时，要分配给它合理的空间和大小</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>JAVA中的很多类都有它的默认的空间分配大小。对于StringBuffer类来讲，默认的分配空间大小是16个字符。如果在程序中使用StringBuffer的空间大小不是16个字符，那么就必须进行正确的初始化。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（4） 避免生成不太使用或生命周期短的对象或变量。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>对于这种情况，因该定义一个对象缓冲池。以为管理一个对象缓冲池的开销要比频繁的生成和回收对象的开销小的多。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>（5） 只在对象作用范围内进行初始化。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>JAVA允许在代码的任何地方定义和初始化对象。这样，就可以只在对象作用的范围内进行初始化。从而节约系统的开销。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>例：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>SomeObject so=new SomeObject();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>If(x==1) then</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Foo=so.getXX();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>可以修改为：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>if(x==1) then</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>SomeObject so=new SomeObject();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Foo=so.getXX();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>2．异常(Exceptions)</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>JAVA语言中提供了try/catch来发方便用户捕捉异常，进行异常的处理。但是如果使用不当，也会给JAVA程序的性能带来影响。因此，要注意以下两点。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(1) 避免对应用程序的逻辑使用try/catch</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>如果可以用if,while等逻辑语句来处理，那么就尽可能的不用try/catch语句</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(2) 重用异常</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>在必须要进行异常的处理时，要尽可能的重用已经存在的异常对象。以为在异常的处理中，生成一个异常对象要消耗掉大部分的时间。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>3. 线程(Threading)</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>一个高性能的应用程序中一般都会用到线程。因为线程能充分利用系统的资源。在其他线程因为等待硬盘或网络读写而 时，程序能继续处理和运行。但是对线程运用不当，也会影响程序的性能。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>例2：正确使用Vector类</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Vector主要用来保存各种类型的对象（包括相同类型和不同类型的对象）。但是在一些情况下使用会给程序带来性能上的影响。这主要是由Vector类的两个特点所决定的。第一，Vector提供了线程的安全保护功能。即使Vector类中的许多方法同步。但是如果你已经确认你的应用程序是单线程，这些方法的同步就完全不必要了。第二，在Vector查找存储的各种对象时，常常要花很多的时间进行类型的匹配。而当这些对象都是同一类型时，这些匹配就完全不必要了。因此，有必要设计一个单线程的，保存特定类型对象的类或集合来替代Vector类.用来替换的程序如下（StringVector.java）：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public class StringVector </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>private String [] data;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>private int count;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public StringVector() { this(10); // default size is 10 }</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public StringVector(int initialSize) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>data = new String[initialSize];</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public void add(String str) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>// ignore null strings</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>if(str == null) { return; }</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>ensureCapacity(count + 1);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>data[count++] = str;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2></FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>private void ensureCapacity(int minCapacity) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>int oldCapacity = data.length;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>if (minCapacity &gt; oldCapacity) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>String oldData[] = data;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>int newCapacity = oldCapacity * 2;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>data = new String[newCapacity];</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.arraycopy(oldData, 0, data, 0, count);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public void remove(String str) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>if(str == null) { return // ignore null str }</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>for(int i = 0; i &lt; count; i++) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{ </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>// check for a match</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>if(data[i].equals(str)) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.arraycopy(data,i+1,data,i,count-1); // copy data </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>// allow previously valid array element be gc'd</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>data[--count] = null;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>return;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public final String getStringAt(int index) {</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>if(index &lt; 0) { return null; } </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>else if(index &gt; count)</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{ </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>return null; // index is &gt; # strings</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>else { return data[index]; // index is good }</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>/* * * * * * * * * * * * * * * *StringVector.java * * * * * * * * * * * * * * * * */</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>因此，代码：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Vector Strings=new Vector();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Strings.add(“One”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Strings.add(“Two”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>String Second=(String)Strings.elementAt(1);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>可以用如下的代码替换：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>StringVector Strings=new StringVector();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Strings.add(“One”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Strings.add(“Two”);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>String Second=Strings.getStringAt(1); </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>这样就可以通过优化线程来提高JAVA程序的性能。用于测试的程序如下（TestCollection.java）: </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>import java.util.Vector;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public class TestCollection </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public static void main(String args []) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>TestCollection collect = new TestCollection();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>if(args.length == 0) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.out.println(</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>"Usage: java TestCollection [ vector | stringvector ]");</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.exit(1);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>if(args[0].equals("vector")) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>Vector store = new Vector();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>long start = System.currentTimeMillis();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>for(int i = 0; i &lt; 1000000; i++) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{ </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>store.addElement("string");</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>long finish = System.currentTimeMillis();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.out.println((finish-start));</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>start = System.currentTimeMillis();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>for(int i = 0; i &lt; 1000000; i++) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>String result = (String)store.elementAt(i);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>finish = System.currentTimeMillis();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.out.println((finish-start));</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>else if(args[0].equals("stringvector")) </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>StringVector store = new StringVector();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>long start = System.currentTimeMillis();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>for(int i = 0; i &lt; 1000000; i++) { store.add("string"); }</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>long finish = System.currentTimeMillis();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.out.println((finish-start));</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>start = System.currentTimeMillis();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>for(int i = 0; i &lt; 1000000; i++) {</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>String result = store.getStringAt(i);</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>finish = System.currentTimeMillis();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>System.out.println((finish-start));</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>/* * * * * * * * * * * * * * * *TestCollection.java * * * * * * * * * * * * * * * * */</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>测试的结果如下（假设标准的时间为１，越小性能越好）：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14>
<P align=center><FONT size=2><IMG src="http://www.huihoo.com/java/performance/i/01_7_9_4.gif" border=0></FONT></P></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>关于线程的操作，要注意如下几个方面。 </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(1) 防止过多的同步</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>如上所示，不必要的同步常常会造成程序性能的下降。因此，如果程序是单线程，则一定不要使用同步。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(2) 同步方法而不要同步整个代码段</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　　　对某个方法或函数进行同步比对整个代码段进行同步的性能要好。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(3) 对每个对象使用多”锁”的机制来增大并发。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>一般每个对象都只有一个”锁”，这就表明如果两个线程执行一个对象的两个不同的同步方法时，会发生”死锁”。即使这两个方法并不共享任何资源。为了避免这个问题，可以对一个对象实行”多锁”的机制。如下所示：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>class foo</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>private static int var1;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>private static Object lock1=new Object();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>private static int var2;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>private static Object lock2=new Object();</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public static void increment1()</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>synchronized(lock1)</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>var1++;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>public static void increment2()</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>synchronized(lock2)</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>{</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>var2++;</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>}</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>4．输入和输出(I/O)</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>输入和输出包括很多方面，但涉及最多的是对硬盘，网络或数据库的读写操作。对于读写操作，又分为有缓存和没有缓存的；对于数据库的操作，又可以有多种类型的JDBC驱动器可以选择。但无论怎样，都会给程序的性能带来影响。因此，需要注意如下几点：</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(1) 使用输入输出缓冲</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　　　尽可能的多使用缓存。但如果要经常对缓存进行刷新（flush）,则建议不要使用缓存。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(2) 输出流(Output Stream)和Unicode字符串 </FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　　　当时用Output Stream和Unicode字符串时，Write类的开销比较大。因为它要实现Unicode到字节(byte)的转换.因此，如果可能的话,在使用Write类之前就实现转换或用OutputStream类代替Writer类来使用。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(3) 当需序列化时使用transient</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　　　当序列化一个类或对象时，对于那些原子类型（atomic）或可以重建的原素要表识为transient类型。这样就不用每一次都进行序列化。如果这些序列化的对象要在网络上传输，这一小小的改变对性能会有很大的提高。　　</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(4) 使用高速缓存（Cache）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　　　对于那些经常要使用而又不大变化的对象或数据，可以把它存储在高速缓存中。这样就可以提高访问的速度。这一点对于从数据库中返回的结果集尤其重要。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(5) 使用速度快的JDBC驱动器（Driver）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>　　　JAVA对访问数据库提供了四种方法。这其中有两种是JDBC驱动器。一种是用JAVA外包的本地驱动器；另一种是完全的JAVA驱动器。具体要使用哪一种得根据JAVA布署的环境和应用程序本身来定。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><B><FONT size=2>5.一些其他的经验和技巧</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(1) 使用局部变量</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(2) 避免在同一个类中动过调用函数或方法(get或set)来设置或调用变量。</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(3) 避免在循环中生成同一个变量或调用同一个函数（参数变量也一样）</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(4) 尽可能的使用static,final,private等关键字</FONT></TD></TR></TBODY></TABLE>
<TABLE width=760 align=center>
<TBODY>
<TR>
<TD class=a14><FONT size=2>(5) 当复制大量数据时，使用System.arraycopy()命令。 <BR></FONT></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/faintbear/aggbug/11615.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/faintbear/" target="_blank">小力力力</a> 2005-08-31 11:40 <a href="http://www.blogjava.net/faintbear/archive/2005/08/31/11615.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.util (转)</title><link>http://www.blogjava.net/faintbear/archive/2005/04/19/3449.html</link><dc:creator>小力力力</dc:creator><author>小力力力</author><pubDate>Tue, 19 Apr 2005 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/faintbear/archive/2005/04/19/3449.html</guid><wfw:comment>http://www.blogjava.net/faintbear/comments/3449.html</wfw:comment><comments>http://www.blogjava.net/faintbear/archive/2005/04/19/3449.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/faintbear/comments/commentRss/3449.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/faintbear/services/trackbacks/3449.html</trackback:ping><description><![CDATA[<DIV class=postTitle><A href="http://blog.csdn.net/WalkingWithJava/archive/2005/04/18/353229.aspx">java.util</A>
<SCRIPT language=javascript>document.title="java.util - "+document.title</SCRIPT>
 </DIV>
<DIV class=postText>
<P class=MsoTitle style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="COLOR: navy"><FONT size=5><STRONG><FONT face="Courier New">Interface 
<P></P></FONT></STRONG></FONT></SPAN>
<P></P>
<P class=MsoSubtitle style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><STRONG><FONT face="Courier New" color=#0000ff size=5>Collection</FONT></STRONG></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN><FONT face="Courier New"><STRONG>RetainAll</STRONG> </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">：保留两个</SPAN><SPAN lang=EN-US><FONT face="Courier New">Collection</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">的交集。注意，如果该</SPAN><SPAN lang=EN-US><FONT face="Courier New">Collection</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">是由</SPAN><SPAN lang=EN-US><FONT face="Courier New">Arrays.asList</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">转换而来，那么这个方法会失败。因为转换来的</SPAN><SPAN lang=EN-US><FONT face="Courier New">List</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">接口不支持这个方法</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN lang=EN-US><FONT face="Courier New">Samples</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>public static void collectionTest()</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>{</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Collection c1 = new ArrayList();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Collection c2 = new ArrayList();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>c1.add("aaa");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>c1.add("bbb");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>c1.add("ccc");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>c2.add("ddd");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>c2.add("ccc");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>c2.add("eee");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>boolean isRetainSucceed = false;</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>isRetainSucceed = c2.retainAll(c1);</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("isRetainSucceed = " + isRetainSucceed);</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("********** print collection c2 values ");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>for (Iterator iter = c2.iterator(); iter.hasNext();)</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>String s = (String) iter.next();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("s = " + s);</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoSubtitle style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><A title="interface in java.util" href="http://blog.csdn.net/jdk142/api/java/util/Enumeration.html" target=classFrame><SPAN style="TEXT-DECORATION: none; text-underline: none"><STRONG><FONT face="Courier New" size=5>Enumeration</FONT></STRONG></SPAN></A></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>太简单，参考文档</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoSubtitle style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><A title="interface in java.util" href="http://blog.csdn.net/jdk142/api/java/util/Comparator.html" target=classFrame><SPAN style="TEXT-DECORATION: none; text-underline: none"><STRONG><FONT face="Courier New" size=5>Comparator</FONT></STRONG></SPAN></A></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>未使用过</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoSubtitle style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><STRONG><FONT face="Courier New" color=#0000ff size=5>EventListener</FONT></STRONG></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>空接口</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoSubtitle style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><STRONG><FONT face="Courier New" color=#0000ff size=5>Iterator</FONT></STRONG></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">和</SPAN><SPAN lang=EN-US><A title="interface in java.util" href="http://blog.csdn.net/jdk142/api/java/util/Enumeration.html" target=classFrame><SPAN style="COLOR: black; TEXT-DECORATION: none; text-underline: none"><FONT face="Courier New">Enumeration</FONT></SPAN></A><FONT face="Courier New"> </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">的不同点：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>1．</FONT><SPAN style="FONT: 7pt 'Times New Roman'"> </SPAN></SPAN><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">允许遍历</SPAN><SPAN lang=EN-US><FONT face="Courier New">Collection</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">时删除对象</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>2．</FONT><SPAN style="FONT: 7pt 'Times New Roman'"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>方法名字可读性更好</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoSubtitle style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><STRONG><FONT face="Courier New" color=#0000ff size=5>List</FONT></STRONG></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">实现的四个类：</SPAN><SPAN lang=EN-US><A title="class in java.util" href="http://blog.csdn.net/jdk142/api/java/util/AbstractList.html"><FONT face="Courier New"><SPAN style="mso-field-code: 'HYPERLINK '/jdk142/api/java/util/AbstractList.html'o Ȭlass in java.util''">AbstractList</SPAN><SPAN style="COLOR: black; TEXT-DECORATION: none; text-underline: none">, <SPAN style="mso-field-code: 'HYPERLINK '/jdk142/api/java/util/ArrayList.html'o Ȭlass in java.util''"><U><SPAN style="COLOR: blue">ArrayList</SPAN></U></SPAN>, <SPAN style="mso-field-code: 'HYPERLINK '/jdk142/api/java/util/LinkedList.html'o Ȭlass in java.util''"><U><SPAN style="COLOR: blue">LinkedList</SPAN></U></SPAN>, <SPAN style="mso-field-code: 'HYPERLINK '/jdk142/api/java/util/Vector.html'o Ȭlass in java.util''"><U><SPAN style="COLOR: blue">Vector</SPAN></U></SPAN> </SPAN></FONT></A></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN lang=EN-US><FONT face="Courier New">List </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">特点：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>1．</FONT><SPAN style="FONT: 7pt 'Times New Roman'"> </SPAN></SPAN><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">允许重复元素，允许</SPAN><SPAN lang=EN-US><FONT face="Courier New">null</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">元素</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>2．</FONT><SPAN style="FONT: 7pt 'Times New Roman'"> </SPAN></SPAN><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">推荐用</SPAN><SPAN lang=EN-US><FONT face="Courier New">Iterator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">遍历，而不是用索引</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><B><SPAN lang=EN-US style="COLOR: navy"><FONT face="Courier New">addAll : </FONT></SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">加入</SPAN><SPAN lang=EN-US><FONT face="Courier New">Collection</FONT></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><FONT face="Courier New"><B><SPAN lang=EN-US style="COLOR: navy">containsAll</SPAN></B><SPAN lang=EN-US style="COLOR: navy"> :</SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">是否包含</SPAN><SPAN lang=EN-US><FONT face="Courier New">Collection</FONT></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><FONT face="Courier New"><B><SPAN lang=EN-US style="COLOR: navy">retainAll</SPAN></B><SPAN lang=EN-US> : </SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">保留和</SPAN><SPAN lang=EN-US><FONT face="Courier New">Collection</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">的交集</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><FONT face="Courier New"><B><SPAN lang=EN-US style="COLOR: navy">subList</SPAN></B><SPAN lang=EN-US> : </SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">返回指定索引区间的子</SPAN><SPAN lang=EN-US><FONT face="Courier New">List</FONT></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><FONT face="Courier New"><B><SPAN lang=EN-US style="COLOR: navy">ListIterator</SPAN></B><SPAN lang=EN-US> </SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>1．</FONT><SPAN style="FONT: 7pt 'Times New Roman'"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>提供元素的双向遍历，而不是单向</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>2．</FONT><SPAN style="FONT: 7pt 'Times New Roman'"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>遍历时可改变存储的元素</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>3．</FONT><SPAN style="FONT: 7pt 'Times New Roman'"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>可动态插入元素，插入的元素在当前操作元素的上一个位置</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN lang=EN-US><FONT face="Courier New">Samples</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>public static void ListTest(){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**********ListTest begin:");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>List list = new ArrayList();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>list.add("aaa");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>list.add("bbb");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>list.add("ccc");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>ListIterator iter = list.listIterator();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**************** Iterating List forward :");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>while(iter.hasNext()){</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>String s = (String)iter.next();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**********element = " + s);</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**************** Iterating List backward :");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>while(iter.hasPrevious()){</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>String s = (String)iter.previous();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**********element = " + s);</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**************** Add element into List :");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>while(iter.hasNext()){</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>int i = iter.nextIndex();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if (i==2)</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>iter.add("ddd");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>String s = (String)iter.next();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**********element = " + s);</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**************** Iterating List backward after add element:");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>while(iter.hasPrevious()){</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>String s = (String)iter.previous();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**********element = " + s);</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**********ListTest end:");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoSubtitle style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><STRONG><FONT face="Courier New" color=#0000ff size=5>Map </FONT></STRONG></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN><FONT face="Courier New"><FONT size=3><STRONG>KeySet</STRONG> :</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">返回</SPAN><SPAN lang=EN-US><FONT face="Courier New">Set</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">对象，然后可以遍历这个</SPAN><SPAN lang=EN-US><FONT face="Courier New">Set</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">。其中的每个元素都是</SPAN><SPAN lang=EN-US><FONT face="Courier New">Map.Entry</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">对象</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><FONT face="Courier New"><B><SPAN lang=EN-US style="COLOR: navy">Map.Entry.setValue</SPAN></B><SPAN lang=EN-US> :</SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">在遍历</SPAN><SPAN lang=EN-US><FONT face="Courier New">Entry</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">对象时，可以改变该</SPAN><SPAN lang=EN-US><FONT face="Courier New">Key</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">对应的</SPAN><SPAN lang=EN-US><FONT face="Courier New">Value</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">值</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN lang=EN-US><FONT face="Courier New">Samples</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>public static void mapEntrySetTest(){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**********mapEntrySetTest begin:");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Map map = new HashMap();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>map.put("first","aaa");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>map.put("second","bbb");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>map.put("third","ccc");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>map.put("fourth","ddd");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Set set = map.entrySet();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Map.Entry entry = null;</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("********** print values in map :");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>for(Iterator iter = set.iterator();iter.hasNext();){</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>entry = (Map.Entry)iter.next();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("Key is :" + entry.getKey() + " and Value is :" + entry.getValue());</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>entry.setValue((String)entry.getValue() + "_setValueTest");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("********** After set value ,iterating values in map :");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>for(Iterator iter = set.iterator();iter.hasNext();){</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>entry = (Map.Entry)iter.next();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("Key is :" + entry.getKey() + " and Value is :" + entry.getValue());<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("**********mapEntrySetTest end:");</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT face="Courier New"><B><SPAN lang=EN-US style="FONT-SIZE: 14pt; COLOR: blue; mso-bidi-font-size: 12.0pt">Observable</SPAN></B><SPAN lang=EN-US><FONT size=3> and </FONT></SPAN><B><SPAN lang=EN-US style="FONT-SIZE: 14pt; COLOR: blue; mso-bidi-font-size: 12.0pt">Observer</SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>暂未想通</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN lang=EN-US style="FONT-SIZE: 14pt; COLOR: blue; mso-bidi-font-size: 12.0pt"><FONT face="Courier New">RandomAccess</FONT></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">空接口。实现这个接口的</SPAN><SPAN lang=EN-US><FONT face="Courier New">List</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">实现品，表示他们支持高速的随机访问元素。如果实现这个接口，理论上</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>for (int i=0, n=list.size(); i &lt; n; i++)</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>list.get(i);</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>比下面代码要快：</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Courier New" size=3>for (Iterator i=list.iterator(); i.hasNext(); )</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>i.next();</FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=3><FONT face="Courier New"> 
<P></P></FONT></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT face="Courier New"><B><SPAN lang=EN-US style="FONT-SIZE: 14pt; COLOR: blue; mso-bidi-font-size: 12.0pt">Set</SPAN></B><SPAN lang=EN-US><FONT size=3> </FONT></SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'"><FONT size=3>：</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">没什么特别的，和</SPAN><SPAN lang=EN-US><FONT face="Courier New">Collection</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'">差不多<BR><BR><BR>转自:http://blog.csdn.net/WalkingWithJava/</SPAN></FONT></P></DIV><img src ="http://www.blogjava.net/faintbear/aggbug/3449.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/faintbear/" target="_blank">小力力力</a> 2005-04-19 11:25 <a href="http://www.blogjava.net/faintbear/archive/2005/04/19/3449.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 统计单词个数和标点符号</title><link>http://www.blogjava.net/faintbear/archive/2005/04/05/2872.html</link><dc:creator>小力力力</dc:creator><author>小力力力</author><pubDate>Tue, 05 Apr 2005 03:55:00 GMT</pubDate><guid>http://www.blogjava.net/faintbear/archive/2005/04/05/2872.html</guid><wfw:comment>http://www.blogjava.net/faintbear/comments/2872.html</wfw:comment><comments>http://www.blogjava.net/faintbear/archive/2005/04/05/2872.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/faintbear/comments/commentRss/2872.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/faintbear/services/trackbacks/2872.html</trackback:ping><description><![CDATA[把随机输入的一句话比如:It's only a test!存放在一个char[]的数组中，统计char[]中的单词个数和标点符号的个数。<BR><BR><BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">package&nbsp;com.faintbear;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>import&nbsp;java.io.</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">;<BR><IMG id=Codehighlighter1_59_771_Open_Image onclick="this.style.display='none'; Codehighlighter1_59_771_Open_Text.style.display='none'; Codehighlighter1_59_771_Closed_Image.style.display='inline'; Codehighlighter1_59_771_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_59_771_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_59_771_Closed_Text.style.display='none'; Codehighlighter1_59_771_Open_Image.style.display='inline'; Codehighlighter1_59_771_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test</SPAN><SPAN id=Codehighlighter1_59_771_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_59_771_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_117_769_Open_Image onclick="this.style.display='none'; Codehighlighter1_117_769_Open_Text.style.display='none'; Codehighlighter1_117_769_Closed_Image.style.display='inline'; Codehighlighter1_117_769_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_117_769_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_117_769_Closed_Text.style.display='none'; Codehighlighter1_117_769_Open_Image.style.display='inline'; Codehighlighter1_117_769_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&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;throws&nbsp;Exception</SPAN><SPAN id=Codehighlighter1_117_769_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_117_769_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BufferedReader&nbsp;br&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;BufferedReader(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;InputStreamReader(System.</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;str&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;br.readLine();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(str&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Exception(</SPAN><SPAN style="COLOR: #000000">""</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">[]&nbsp;c&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;str.toCharArray();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;words&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;ip&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean&nbsp;wordflag&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><IMG id=Codehighlighter1_388_613_Open_Image onclick="this.style.display='none'; Codehighlighter1_388_613_Open_Text.style.display='none'; Codehighlighter1_388_613_Closed_Image.style.display='inline'; Codehighlighter1_388_613_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_388_613_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_388_613_Closed_Text.style.display='none'; Codehighlighter1_388_613_Open_Image.style.display='inline'; Codehighlighter1_388_613_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;i</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">c.length;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN id=Codehighlighter1_388_613_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_388_613_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_455_546_Open_Image onclick="this.style.display='none'; Codehighlighter1_455_546_Open_Text.style.display='none'; Codehighlighter1_455_546_Closed_Image.style.display='inline'; Codehighlighter1_455_546_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_455_546_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_455_546_Closed_Text.style.display='none'; Codehighlighter1_455_546_Open_Image.style.display='inline'; Codehighlighter1_455_546_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">((c[i]</SPAN><SPAN style="COLOR: #000000">&gt;=</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;c[i]&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">z</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;(c[i]&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;c[i]&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">Z</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">))</SPAN><SPAN id=Codehighlighter1_455_546_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #80