﻿<?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-天猫的Blog-文章分类-Java基础</title><link>http://www.blogjava.net/tianmaoye/category/31980.html</link><description>...从明天起，做一个幸福的人。...喂马，劈柴，周游世界。...从明天起，开始关心粮食和蔬菜。...我有一所房子，面朝大海春暖花开......</description><language>zh-cn</language><lastBuildDate>Fri, 25 Jul 2008 11:39:53 GMT</lastBuildDate><pubDate>Fri, 25 Jul 2008 11:39:53 GMT</pubDate><ttl>60</ttl><item><title>JAVA字符串处理函数列表一览</title><link>http://www.blogjava.net/tianmaoye/articles/217534.html</link><dc:creator>飞行鱼</dc:creator><author>飞行鱼</author><pubDate>Fri, 25 Jul 2008 10:07:00 GMT</pubDate><guid>http://www.blogjava.net/tianmaoye/articles/217534.html</guid><wfw:comment>http://www.blogjava.net/tianmaoye/comments/217534.html</wfw:comment><comments>http://www.blogjava.net/tianmaoye/articles/217534.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tianmaoye/comments/commentRss/217534.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tianmaoye/services/trackbacks/217534.html</trackback:ping><description><![CDATA[<div class="date">&nbsp;Java中的字符串也是一连串的字符。但是与许多其他的计算机语言将字符串作为字符数组处理不同，Java将字符串作为String类型对象来处理。将字符串作为内置的对象处理允许Java提供十分丰富的功能特性以方便处理字符串。下面是一些使用频率比较高的函数及其相关说明。 </div>
<div class="entry">
<div class="adsDiv">&nbsp;</div>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />substring()<br />
它有两种形式，第一种是：String substring(int startIndex)<br />
第二种是：String substring(int startIndex,int endIndex)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />concat() 连接两个字符串</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />replace() 替换<br />
它有两种形式，第一种形式用一个字符在调用字符串中所有出现某个字符的地方进行替换，形式如下：<br />
String replace(char original,char replacement)<br />
例如：String s=&#8221;Hello&#8221;.replace(&#8217;l',&#8217;w');<br />
第二种形式是用一个字符序列替换另一个字符序列，形式如下：<br />
String replace(CharSequence original,CharSequence replacement)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />trim() 去掉起始和结尾的空格</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />valueOf() 转换为字符串</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />toLowerCase() 转换为小写</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />toUpperCase() 转换为大写</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />length() 取得字符串的长度<br />
例：<br />
char chars[]={&#8217;a',&#8217;b&#8217;.&#8217;c'};<br />
String s=new String(chars);<br />
int len=s.length();</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />charAt() 截取一个字符<br />
例：<br />
char ch;<br />
ch=&#8221;abc&#8221;.charAt(1); <br />
返回值为&#8217;b&#8217;</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />getChars() 截取多个字符<br />
void getChars(int sourceStart,int sourceEnd,char target[],int targetStart)<br />
sourceStart 指定了子串开始字符的下标<br />
sourceEnd 指定了子串结束后的下一个字符的下标。因此，子串包含从sourceStart到sourceEnd-1的字符。<br />
target 指定接收字符的数组<br />
targetStart target中开始复制子串的下标值<br />
例：<br />
String s=&#8221;this is a demo of the getChars method.&#8221;;<br />
char buf[]=new char[20];<br />
s.getChars(10,14,buf,0);</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />getBytes()<br />
替代getChars()的一种方法是将字符存储在字节数组中，该方法即getBytes()<br />
例：<br />
String s = &#8220;Hello!你好！&#8221;; <br />
byte[] bytes = s.getBytes(); </p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />toCharArray()<br />
例：<br />
String s = &#8220;Hello!你好！&#8221;; <br />
char[] ss = s.toCharArray();</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />equals()和equalsIgnoreCase() 比较两个字符串</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />regionMatches() 用于比较一个字符串中特定区域与另一特定区域，它有一个重载的形式允许在比较中忽略大小写。<br />
boolean regionMatches(int startIndex,String str2,int<br />
str2StartIndex,int numChars)<br />
boolean regionMatches(boolean ignoreCase,int startIndex,String<br />
str2,int str2StartIndex,int numChars)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />startsWith()和endsWith()<br />
startsWith()方法决定是否以特定字符串开始，endWith()方法决定是否以特定字符串结束</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />equals()和==<br />
equals()方法比较字符串对象中的字符，==运算符比较两个对象是否引用同一实例。<br />
例：String s1=&#8221;Hello&#8221;;<br />
String s2=new String(s1);<br />
s1.eauals(s2); //true<br />
s1==s2;//false</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />compareTo()和compareToIgnoreCase() 比较字符串</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />indexOf()和lastIndexOf()<br />
indexOf() 查找字符或者子串第一次出现的地方。<br />
lastIndexOf() 查找字符或者子串是后一次出现的地方。</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />StringBuffer构造函数<br />
StringBuffer定义了三个构造函数：<br />
StringBuffer()<br />
StringBuffer(int size)<br />
StringBuffer(String str)<br />
StringBuffer(CharSequence chars)</p>
<p>下面是StringBuffer相关的函数：<br />
<img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />length()和capacity()<br />
一个StringBuffer当前长度可通过length()方法得到,而整个可分配空间通过capacity()方法得到。</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />ensureCapacity() 设置缓冲区的大小<br />
void ensureCapacity(int capacity)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />setLength() 设置缓冲区的长度<br />
void setLength(int len)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />charAt()和setCharAt()<br />
char charAt(int where)<br />
void setCharAt(int where,char ch)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />getChars()<br />
void getChars(int sourceStart,int sourceEnd,char target[],int targetStart)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />append() 可把任何类型数据的字符串表示连接到调用的StringBuffer对象的末尾。<br />
例：int a=42;<br />
StringBuffer sb=new StringBuffer(40);<br />
String s=sb.append(&#8221;a=&#8221;).append(a).append(&#8221;!&#8221;).toString();</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />insert() 插入字符串<br />
StringBuffer insert(int index,String str)<br />
StringBuffer insert(int index,char ch)<br />
StringBuffer insert(int index,Object obj)<br />
index指定将字符串插入到StringBuffer对象中的位置的下标。</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />reverse() 颠倒StringBuffer对象中的字符<br />
StringBuffer reverse()</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />delete()和deleteCharAt() 删除字符<br />
StringBuffer delete(int startIndex,int endIndex)<br />
StringBuffer deleteCharAt(int loc)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />replace() 替换<br />
StringBuffer replace(int startIndex,int endIndex,String str)</p>
<p><img src="http://ntt.cc/wp-content/themes/i3theme-1-5-right/images/bullet-grey.gif"  alt="" />substring() 截取子串<br />
String substring(int startIndex)<br />
String substring(int startIndex,int endIndex)</p>
<!-- 2008/01/22 TEI add Google Adsense Begin --><!-- <p class="submeta">	
--></div>
<img src ="http://www.blogjava.net/tianmaoye/aggbug/217534.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tianmaoye/" target="_blank">飞行鱼</a> 2008-07-25 18:07 <a href="http://www.blogjava.net/tianmaoye/articles/217534.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>String与StringBuffer【转】</title><link>http://www.blogjava.net/tianmaoye/articles/208385.html</link><dc:creator>飞行鱼</dc:creator><author>飞行鱼</author><pubDate>Mon, 16 Jun 2008 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/tianmaoye/articles/208385.html</guid><wfw:comment>http://www.blogjava.net/tianmaoye/comments/208385.html</wfw:comment><comments>http://www.blogjava.net/tianmaoye/articles/208385.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tianmaoye/comments/commentRss/208385.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tianmaoye/services/trackbacks/208385.html</trackback:ping><description><![CDATA[<div class="content" style="overflow: auto" minmax_bound="true">
<p minmax_bound="true"><font size="2" minmax_bound="true">String的创建</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp; String s = "hello";<br minmax_bound="true" />
&nbsp; JVM先根据内容"hello"查找对象，如果没有找到，则在heap上创建新对象，并将其赋予s1，否则使用已经存在的对象</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp; String s = new String("hello");<br minmax_bound="true" />
&nbsp; JVM直接在heap上创建新的对象，所以在heap中会出现内容相同，地址不同的String对象</font></p>
<p minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">String的比较</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp; "=="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比较地址<br minmax_bound="true" />
&nbsp; "equals"&nbsp;&nbsp;&nbsp; 比较内容</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp; 举例:<br minmax_bound="true" />
&nbsp; String s1 = "hello";<br minmax_bound="true" />
&nbsp; String s2 = "hello";<br minmax_bound="true" />
&nbsp; String s3 = new String("hello");</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp; s1 == s2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 地址相同<br minmax_bound="true" />
&nbsp; s1 == s3;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 地址不同<br minmax_bound="true" />
&nbsp; s1.equals(s2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 内容相同<br minmax_bound="true" />
&nbsp; s1.equals(s3);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 内容相同</font></p>
<p minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">intern() 方法</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;&nbsp; 查找内容相同(equals())的字符串</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;&nbsp; String s1 = "hello";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // hello不存在，jvm创建新对象 (1)<br minmax_bound="true" />
&nbsp;&nbsp; String s2 = new String("hello");&nbsp;&nbsp;&nbsp; // 创举新对象 (2)，这时heap中存在两个内容为hello的对象<br minmax_bound="true" />
&nbsp;&nbsp; s1 == s2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 地址不同<br minmax_bound="true" />
&nbsp;&nbsp; s1.equals(s2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 内容相同<br minmax_bound="true" />
&nbsp;&nbsp; s2 = s2.intern();&nbsp;&nbsp; // true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 找到对象(1) 并赋予s2<br minmax_bound="true" />
&nbsp;&nbsp; s1 == s2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // true !!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 注意：此时s1,s2同指向(1)</font></p>
<p minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">效率：String 与 StringBuffer</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; 情景1：<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; (1) String result = "hello" + " world";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; (2) StringBuffer result = new String().append("hello").append(" world");</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) 的效率好于 (2)，不要奇怪，这是因为JVM会做如下处理<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 编译前&nbsp;&nbsp; String result = "hello" + " world";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 编译后&nbsp;&nbsp; String result = "hello world";</font></p>
<p minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; 情景2：<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; (1) public String getString(String s1, String s2) {<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return s1 + s2;<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; (2) public String getString(String s1, String s2) {<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new StringBuffer().append(s1).append(s2);<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) 的效率与 (2) 一样，这是因为JVM会做如下处理<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 编译前&nbsp;&nbsp; return s1 + s2;<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 编译后&nbsp;&nbsp; return new StringBuffer().append(s1).append(s2);</font></p>
<p minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; 情景3：<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; (1) String s = "s1";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s += "s2";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s += "s3";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; (2) StringBuffer s = new StringBuffer().append("s1").append("s2").append("s3");</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) 的效率好于(1)，因为String是不可变对象，每次"+="操作都会造成构造新的String对象</font></p>
<p minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; 情景4：<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; (1) StringBuffer s = new StringBuffer();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; 50000; i ++) {<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.append("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; (2) StringBuffer s = new StringBuffer(250000);<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; 50000; i ++) {<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.append("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) 的效率好于 (1)，因为StringBuffer内部实现是char数组，默认初始化长度为16，每当字符串长度大于char<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数组长度的时候，JVM会构造更大的新数组，并将原先的数组内容复制到新数组，(2)避免了复制数组的开销<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; </font></p>
<p minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">关键点<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; 1). 简单的认为 .append() 效率好于 "+" 是错误的！<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; 2). 不要使用 new 创建 String<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; 3). 注意 .intern() 的使用<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; 4). 在编译期能够确定字符串值的情况下，使用"+"效率最高<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; 5). 避免使用 "+=" 来构造字符串<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; 6). 在声明StringBuffer对象的时候，指定合适的capacity，不要使用默认值(18)<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; 7). 注意以下二者的区别不一样<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - String s = "a" + "b";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - String s = "a";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s += "b";</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">String和StringBuffer之概览<br minmax_bound="true" />
　　创建字符串的较佳途径<br minmax_bound="true" />
　　滞留字符串带来的优化<br minmax_bound="true" />
　　连接字符串时的优化技巧<br minmax_bound="true" />
　　借助StringBuffer的初始化过程的优化技巧<br minmax_bound="true" />
　　关键点</font></p>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><strong minmax_bound="true">String和StringBuffer之概览</strong><br minmax_bound="true" />
　　非可变对象一旦创建之后就不能再被改变，可变对象则可以在创建之后被改变。String对象是非可变对象，StringBuffer对象则是可变对象。为获得更佳的性能你需要根据实际情况小心谨慎地选择到底使用这两者中的某一个。下面的话题会作详细的阐述。（注意：这个章节假设读者已经具备Java的String和StringBuffer的相关基础知识。）</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><strong minmax_bound="true"><font size="2" minmax_bound="true">创建字符串的较佳途径</font></strong></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">你可以按照以下方式创建字符串对象：<br minmax_bound="true" />
1. String s1 = "hello";&nbsp;<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; String s2 = "hello";&nbsp;<br minmax_bound="true" />
2. String s3 = new String("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; String s4 = new String("hello");</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">上面哪种方式会带来更好的性能呢？下面的代码片断用来测量二者之间的区别。</font></div>
<div minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">StringTest1.java</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">package com.performance.string;</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">/** This class shows the time taken for creation of <br minmax_bound="true" />
&nbsp;*&nbsp; String literals and String objects.<br minmax_bound="true" />
&nbsp;*/</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">public class StringTest1 {</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">public static void main(String[] args){</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; // create String literals<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;50000;i++){</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; String s1 = "hello";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; String s2 = "hello"; <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for creation of String literals : "<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime - startTime) + " milli seconds" );</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; // create String objects using 'new' keyword&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime1 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;50000;i++){</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; String s3 = new String("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; String s4 = new String("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><font style="background-color: #c0c0c0" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime1 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for creation of String objects : " <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime1 - startTime1)+" milli seconds");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }<br minmax_bound="true" />
}</font><br minmax_bound="true" />
这段代码的输出：<br minmax_bound="true" />
</font><font style="background-color: #c0c0c0" size="2" minmax_bound="true">Time taken for creation of String literals : 0 milli seconds<br minmax_bound="true" />
Time taken for creation of String objects : 170 milli seconds</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" minmax_bound="true"></font><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><strong minmax_bound="true">JVM是怎样处理字符串的呢？</strong><br minmax_bound="true" />
　　Java虚拟机会维护一个内部的滞留字符串对象的列表（唯一字符串的池）来避免在堆内存中产生重复的String对象。当JVM从class文件里加载字符串字面量并执行的时候，它会先检查一下当前的字符串是否已经存在于滞留字符串列表，如果已经存在，那就不会再创建一个新的String对象而是将引用指向已经存在的String对象，JVM会在内部为字符串字面量作这种检查，但并不会为通过new关键字创建的String对象作这种检查。当然你可以明确地使用String.intern()方法强制JVM为通过new关键字创建的String对象作这样的检查。这样可以强制JVM检查内部列表而使用已有的String对象。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">　　所以结论是，JVM会内在地为字符串字面量维护一些唯一的String对象，程序员不需要为字符串字面量而发愁，但是可能会被一些通过new关键字创建的String对象而困扰，不过他们可以使用intern()方法来避免在堆内存上创建重复的String对象来改善Java的运行性能。下一小节会向大家展示更多的信息。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">下图展示了未使用intern()方法来创建字符串的情况。<br minmax_bound="true" />
&nbsp;</font></div>
<p minmax_bound="true"><font size="2" minmax_bound="true"><img style="width: auto; height: auto; minmaxwidth: auto; minmaxheight: auto; maxwidth: 450px" alt="" src="http://www.webdn.com/web_file/program/jsp/060208097/images/20060117201239_1.gif" minmax_bound="true" /> </font></p>
<div minmax_bound="true"><font size="2" minmax_bound="true">　　你可以自己使用==操作符和String.equals()方法来编码测试上面提到的区别。==操作符会返回true如果一些引用指向一个相同的对象但不会判断String对象的内容是否相同；String.equals()方法会返回true如果被操作的String对象的内容相同。对于上面的代码会有s1==s2，因为s1和s2两个引用指向同一个对象，对于上面的代码，s3.equals(s4)会返回true因为两个对象的内容都一样为&#8221;hello&#8221;。你可以从上图看出这种机制。在这里有三个独立的包含了相同的内容（&#8221;hello&#8221;）的对象，实际上我们不需要这么三个独立的对象――因为要运行它们的话既浪费时间又浪费内存。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">　　那么怎样才能确保String对象不会重复呢？下一个话题会涵盖对于内建String机制的兴趣。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><strong minmax_bound="true">滞留字符串的优化作用<br minmax_bound="true" />
</strong>　　同一个字符串对象被重复地创建是不必要的，String.intern()方法可以避免这种情况。下图说明了String.intern()方法是如何工作的，String.intern()方法检查字符串对象的存在性，如果需要的字符串对象已经存在，那么它会将引用指向已经存在的字符串对象而不是重新创建一个。下图描绘了使用了intern()方法的字符串字面量和字符串对象的创建情况。<br minmax_bound="true" />
&nbsp;<br minmax_bound="true" />
<img style="width: auto; height: auto; minmaxwidth: auto; minmaxheight: auto; maxwidth: 450px" alt="" src="http://www.webdn.com/web_file/program/jsp/060208097/images/20060117201219_2.gif" minmax_bound="true" /></font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">下面的例程帮助大家了解String.intern()方法的重要性。<br minmax_bound="true" />
StringTest2.java</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">package com.performance.string;</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">// This class shows the use of intern() method to improve performance<br minmax_bound="true" />
public class StringTest2 {</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">public static void main(String[] args){</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; // create String references like s1,s2,s3...so on..<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; String variables[] = new String[50000];<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for( int i=0;i &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variables[i] = "s"+i;<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; // create String literals<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime0 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variables[i] = "hello";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime0 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for creation of String literals : "<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime0 - startTime0) + " milli seconds" );</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; // create String objects using 'new' keyword&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime1 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variables[i] = new String("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime1 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for creation of String objects with 'new' key word : " <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime1 - startTime1)+" milli seconds");</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; // intern String objects with intern() method&nbsp;&nbsp;&nbsp; <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime2 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variables[i] = new String("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variables[i] = variables[i].intern();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime2 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for creation of String objects with intern(): " <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime2 - startTime2)+" milli seconds");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }<br minmax_bound="true" />
}</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">这是上面那段代码的输出结果：<br minmax_bound="true" />
</font><font style="background-color: #c0c0c0" size="2" minmax_bound="true">Time taken for creation of String literals : 0 milli seconds<br minmax_bound="true" />
Time taken for creation of String objects with 'new' key word : 160 milli seconds<br minmax_bound="true" />
Time taken for creation of String objects with intern(): 60 milli seconds</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" minmax_bound="true"></font><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><strong minmax_bound="true">连接字符串时候的优化技巧<br minmax_bound="true" />
</strong>　　你可以使用+操作符或者String.concat()或者StringBuffer.append()等办法来连接多个字符串，那一种办法具有最佳的性能呢？</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">　　如何作出选择取决于两种情景，第一种情景是需要连接的字符串是在编译期决定的还是在运行期决定的，第二种情景是你使用的是StringBuffer还是String。通常程序员会认为StringBuffer.append()方法会优于+操作符或String.concat()方法，但是在一些特定的情况下这个假想是不成立的。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">1)&nbsp;第一种情景：编译期决定相对于运行期决定<br minmax_bound="true" />
请看下面的StringTest3.java代码和输出结果。</font></div>
<div minmax_bound="true"><br minmax_bound="true" />
<font style="background-color: #c0c0c0" size="2" minmax_bound="true">package com.performance.string;</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">/** This class shows the time taken by string concatenation at compile time and run time.*/<br minmax_bound="true" />
public class StringTest3 {</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp; public static void main(String[] args){<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; //Test the String Concatination<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;5000;i++){<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; String result = "This is"+ "testing the"+ "difference"+ "between"+ <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "String"+ "and"+ "StringBuffer";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for string concatenation using + operator : " <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime - startTime)+ " milli seconds");</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; //Test the StringBuffer Concatination<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime1 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;5000;i++){<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; StringBuffer result = new StringBuffer();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append("This is");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append("testing the");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append("difference");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append("between");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append("String");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append("and");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append("StringBuffer");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><font style="background-color: #c0c0c0" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime1 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for String concatenation using StringBuffer : "<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime1 - startTime1)+ " milli seconds");<br minmax_bound="true" />
&nbsp; }<br minmax_bound="true" />
}<br minmax_bound="true" />
</font>这是上面的代码的输出结果：<br minmax_bound="true" />
</font><font size="2" minmax_bound="true"><font style="background-color: #c0c0c0" minmax_bound="true">Time taken for String concatenation using + operator : 0 milli seconds<br minmax_bound="true" />
Time taken for String concatenation using StringBuffer : 50 milli seconds</font><br minmax_bound="true" />
很有趣地，+操作符居然比StringBuffer.append()方法要快，为什么呢？</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">　　这里编译器的优化起了关键作用，编译器像下面举例的那样简单地在编译期连接多个字符串。它使用编译期决定取代运行期决定，在你使用new关键字来创建String对象的时候也是如此。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">编译前：<br minmax_bound="true" />
String result = "This is"+"testing the"+"difference"+"between"+"String"+"and"+"StringBuffer";<br minmax_bound="true" />
编译后：<br minmax_bound="true" />
String result = "This is testing the difference between String and StringBuffer";</font></div>
<div minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">这里String对象在编译期就决定了而StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法预先知道的时候，编译期决定作用于字符串的值可以预先知道的时候，下面是一个例子。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">编译前：<br minmax_bound="true" />
public String getString(String str1,String str2) {<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; return str1+str2;<br minmax_bound="true" />
}<br minmax_bound="true" />
编译后：<br minmax_bound="true" />
return new StringBuffer().append(str1).append(str2).toString();<br minmax_bound="true" />
运行期决定需要更多的时间来运行。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">2)&nbsp;第二种情景：使用StringBuffer取代String<br minmax_bound="true" />
看看下面的代码你会发现与情景一相反的结果――连接多个字符串的时候StringBuffer要比String快。<br minmax_bound="true" />
StringTest4.java</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">package com.performance.string;</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">/** This class shows the time taken by string concatenation <br minmax_bound="true" />
using + operator and StringBuffer&nbsp; */<br minmax_bound="true" />
public class StringTest4 {</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;public static void main(String[] args){<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; //Test the String Concatenation using + operator<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; String result = "hello";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;1500;i++){<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result += "hello";<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for string concatenation using + operator : "<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime - startTime)+ " milli seconds");</font></div>
<div minmax_bound="true"><font style="background-color: #c0c0c0" size="2" minmax_bound="true">&nbsp;&nbsp;&nbsp; //Test the String Concatenation using StringBuffer<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; long startTime1 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; StringBuffer result1 = new StringBuffer("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;1500;i++){<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result1.append("hello");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><font style="background-color: #c0c0c0" minmax_bound="true">&nbsp;&nbsp;&nbsp; long endTime1 = System.currentTimeMillis();<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; System.out.println("Time taken for string concatenation using StringBuffer :&nbsp; " <br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + (endTime1 - startTime1)+ " milli seconds");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp; }<br minmax_bound="true" />
}<br minmax_bound="true" />
</font>这是上面的代码的输出结果：<br minmax_bound="true" />
</font><font style="background-color: #c0c0c0" size="2" minmax_bound="true">Time taken for string concatenation using + operator : 280 milli seconds<br minmax_bound="true" />
Time taken for String concatenation using StringBuffer : 0 milli seconds</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">看得出StringBuffer.append()方法要比+操作符要快得多，为什么呢？</font></div>
<div minmax_bound="true"><br minmax_bound="true" />
<font size="2" minmax_bound="true">　　原因是两者都是在运行期决定字符串对象，但是+操作符使用不同于StringBuffer.append()的规则通过String和StringBuffer来完成字符串连接操作。（译注：什么样的规则呢？）</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><strong minmax_bound="true">借助StringBuffer的初始化过程的优化技巧</strong><br minmax_bound="true" />
　　你可以通过StringBuffer的构造函数来设定它的初始化容量，这样可以明显地提升性能。这里提到的构造函数是StringBuffer(int length)，length参数表示当前的StringBuffer能保持的字符数量。你也可以使用ensureCapacity(int minimumcapacity)方法在StringBuffer对象创建之后设置它的容量。首先我们看看StringBuffer的缺省行为，然后再找出一条更好的提升性能的途径。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><strong minmax_bound="true">StringBuffer的缺省行为：</strong><br minmax_bound="true" />
　　StringBuffer在内部维护一个字符数组，当你使用缺省的构造函数来创建StringBuffer对象的时候，因为没有设置初始化字符长度，StringBuffer的容量被初始化为16个字符，也就是说缺省容量就是16个字符。当StringBuffer达到最大容量的时候，它会将自身容量增加到当前的2倍再加2，也就是（2*旧值+2）。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">　　如果你使用缺省值，初始化之后接着往里面追加字符，在你追加到第16个字符的时候它会将容量增加到34（2*16+2），当追加到34个字符的时候就会将容量增加到70（2*34+2）。无论何事只要StringBuffer到达它的最大容量它就不得不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍――这也太昂贵了点。所以总是给StringBuffer设置一个合理的初始化容量值是错不了的，这样会带来立竿见影的性能增益。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">　　我利用两个StringBuffer重新测试了上面的StringTest4.java代码，一个未使用初始化容量值而另一个使用了。这次我追加了50000个&#8217;hello&#8217;对象没有使用+操作符。区别是我使用StringBuffer(250000)的构造函数来初始化第二个StringBuffer了。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">输出结果如下：<br minmax_bound="true" />
</font><font style="background-color: #c0c0c0" size="2" minmax_bound="true">Time taken for String concatenation using StringBuffer with out setting size: 280 milli seconds<br minmax_bound="true" />
Time taken for String concatenation using StringBuffer with setting size: 0 milli seconds</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">StringBuffer初始化过程的调整的作用由此可见一斑。所以，使用一个合适的容量值来初始化StringBuffer永远都是一个最佳的建议。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><strong minmax_bound="true">关键点</strong><br minmax_bound="true" />
1.&nbsp;无论何时只要可能的话使用字符串字面量来常见字符串而不是使用new关键字来创建字符串。<br minmax_bound="true" />
2.&nbsp;无论何时当你要使用new关键字来创建很多内容重复的字符串的话，请使用String.intern()方法。<br minmax_bound="true" />
3.&nbsp;+操作符会为字符串连接提供最佳的性能――当字符串是在编译期决定的时候。<br minmax_bound="true" />
4.&nbsp;如果字符串在运行期决定，使用一个合适的初期容量值初始化的StringBuffer会为字符串连接提供最佳的性能。</font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"></font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"></font></div>
<div minmax_bound="true"><font size="2" minmax_bound="true"><strong minmax_bound="true">String与StringBuffer的比较</strong><br minmax_bound="true" />
String类提供了一些方法，用来进行字符串的比较。这个类实现了Object父类的equals()方法，用来比较两种字符串的值是否相等。同时还增加了equalsIgnoreCase()方法可以忽略两个字符串大小写的区别。下面是这两种方法的例子。<br minmax_bound="true" />
【例6-6】<br minmax_bound="true" />
public class E6_6{<br minmax_bound="true" />
&nbsp;public static void main(String args[]) { <br minmax_bound="true" />
&nbsp;&nbsp;String s1="a";<br minmax_bound="true" />
&nbsp;&nbsp;String s2=new String("a");<br minmax_bound="true" />
&nbsp;&nbsp;String s3="A";<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(s1.equals(s2));<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(s1.equals(s3));<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(s1.equalsIgnoreCase(s3));<br minmax_bound="true" />
&nbsp;}<br minmax_bound="true" />
}<br minmax_bound="true" />
上例的输出是<br minmax_bound="true" />
true<br minmax_bound="true" />
flase<br minmax_bound="true" />
true </font>
<p minmax_bound="true"><font size="2" minmax_bound="true">但是StringBuffer类并没有实现Objcet类的Equals方法，所以不能用这个方法来比较两个StringBuffer类的字符串是否相等，如下例所示。<br minmax_bound="true" />
【例6-7】<br minmax_bound="true" />
public class E6_7{<br minmax_bound="true" />
&nbsp;public static void main(String args[]) { <br minmax_bound="true" />
&nbsp;&nbsp;StringBuffer s1=new StringBuffer("a");<br minmax_bound="true" />
&nbsp;&nbsp;StringBuffer s2=new StringBuffer("a");<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(s1.equals(s2));<br minmax_bound="true" />
&nbsp;&nbsp;<br minmax_bound="true" />
&nbsp;}<br minmax_bound="true" />
}<br minmax_bound="true" />
程序输出：false</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">除了用equalse方法来比较两个字符串外，还可以用==来比较字符串。与equalse方法不同的是，==不是比较两个字符串的值是否相等，而是比较几个字符串的引用是否指向同一个实例。如例6-8所示。<br minmax_bound="true" />
【例6-8】<br minmax_bound="true" />
public class E6_8{<br minmax_bound="true" />
&nbsp;public static void main(String args[]) { <br minmax_bound="true" />
&nbsp;&nbsp;String s1="a";<br minmax_bound="true" />
&nbsp;&nbsp;String s2="a";<br minmax_bound="true" />
&nbsp;&nbsp;String s3=new String("a");<br minmax_bound="true" />
&nbsp;&nbsp;String s4=new String("a");<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(s1==s2);<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(s3==s4);<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(s1==s3);<br minmax_bound="true" />
&nbsp;&nbsp;<br minmax_bound="true" />
&nbsp;}<br minmax_bound="true" />
&nbsp;<br minmax_bound="true" />
}<br minmax_bound="true" />
上面的程序段输出：<br minmax_bound="true" />
true<br minmax_bound="true" />
false<br minmax_bound="true" />
false<br minmax_bound="true" />
与上例进行比较，不仅可以看出来==与equals的区别，还可以看到字面量的String的特殊之外。<br minmax_bound="true" />
对于字面量的String，只要字符串的值是相等的，不论有多少个引用都是指向同一块内存，不再另外分配空间。而用new关键字生成的实例则不同，每当用new实例化一次，分配该实例自己的内存空间。上例的存储方式如图所示：</font></p>
<p minmax_bound="true"><font size="2" minmax_bound="true">&nbsp;<br minmax_bound="true" />
图6-1&nbsp; s1、s2、s3、s4的区别<br minmax_bound="true" />
下面再通过另一个例子来看String和StringBuffer的区别。<br minmax_bound="true" />
【例6-9】<br minmax_bound="true" />
public class E6_9{<br minmax_bound="true" />
&nbsp;public static void main(String args[]) { <br minmax_bound="true" />
&nbsp;&nbsp;String s1="a";<br minmax_bound="true" />
&nbsp;&nbsp;StringBuffer sb1=new StringBuffer("a");<br minmax_bound="true" />
&nbsp;&nbsp;<br minmax_bound="true" />
&nbsp;&nbsp;StringBuffer sb2=sb1;<br minmax_bound="true" />
&nbsp;&nbsp;String s2="a"+"b";<br minmax_bound="true" />
&nbsp;&nbsp;sb1.append("b");<br minmax_bound="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(s1==s2);<br minmax_bound="true" />
&nbsp;&nbsp;System.out.println(sb1==sb2);<br minmax_bound="true" />
&nbsp;&nbsp;<br minmax_bound="true" />
&nbsp;}&nbsp;<br minmax_bound="true" />
}<br minmax_bound="true" />
上例输出的是：<br minmax_bound="true" />
flase<br minmax_bound="true" />
true<br minmax_bound="true" />
上例可以证明这样的结论：String是不可变长的字符串，对String做任何的修改将生成新的字符串，而StringBuffer是可变长的字符串，不论怎么更动还是同一个字符串。<br minmax_bound="true" />
</font></p>
</div>
</div>
<img src ="http://www.blogjava.net/tianmaoye/aggbug/208385.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tianmaoye/" target="_blank">飞行鱼</a> 2008-06-16 17:27 <a href="http://www.blogjava.net/tianmaoye/articles/208385.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jdk与jre的区别</title><link>http://www.blogjava.net/tianmaoye/articles/205617.html</link><dc:creator>飞行鱼</dc:creator><author>飞行鱼</author><pubDate>Tue, 03 Jun 2008 09:56:00 GMT</pubDate><guid>http://www.blogjava.net/tianmaoye/articles/205617.html</guid><wfw:comment>http://www.blogjava.net/tianmaoye/comments/205617.html</wfw:comment><comments>http://www.blogjava.net/tianmaoye/articles/205617.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tianmaoye/comments/commentRss/205617.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tianmaoye/services/trackbacks/205617.html</trackback:ping><description><![CDATA[<p>对于java初学者来说，往往不懂区分jdk和jre的区别，实际上这两个东西差别很大的，有必要了解一下：</p>
<p>简单的说JDK是面向开发人员使用的SDK，它提供了Java的开发环境和运行环境。SDK是Software Development Kit 一般指软件开发包，可以包括函数库、编译程序等。<br />
&nbsp;&nbsp; JDK就是Java Development Kit<br />
JRE是Java Runtime Enviroment是指Java的运行环境，是面向Java程序的使用者，而不是开发者。</p>
<p>如果安装了JDK，会发同你的电脑有两套JRE，一套位于 \jre 另外一套位于 C:\Program Files\Java\j2re1.4.1_01 目录下，后面这套比前面那套少了Server端的Java虚拟机，不过直接将前面那套的Server端Java虚拟机复制过来就行了。而且在安装JDK可以选择是否安装这个位于 C:\Program Files\Jav a 目录下的JRE。如果你只安装JRE，而不是JDK，那么只会在 C:\Program Files\Java 目录下安装唯一的一套JRE。 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; JRE的地位就象一台PC机一样，我们写好的Win32应用程序需要操作系统帮我们运行，同样的，我们编写的Java程序也必须要JRE才能运行。所以当你装完JDK后，如果分别在硬盘上的两个不同地方安装了两套JRE，那么你可以想象你的电脑有两台虚拟的Java PC机，都具有运行Java程序的功能。所以我们可以说，只要你的电脑安装了JRE，就可以正确运行Jav a应用程序。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、为什么Sun要让JDK安装两套相同的JRE？这是因为JDK里面有很多用Java所编写的开发工具（如javac.exe、jar.exe等），而且都放置在 \lib\tools.jar 里。从下面例子可以看出，先将tools.jar改名为tools1.jar，然后运行javac.exe，显示如下结果： Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/javac /Main 这个意思是说，你输入javac.exe与输入 java -cp c:\jdk\lib\tools.jar com.sun.tools.javac.Main 是一样的，会得到相同的结果。从这里我们可以证明javac.exe只是一个包装器（Wrapper），而制作的目的是为了让开发者免于输入太长的指命。而且可以发现\lib目录下的程序都很小，不大于2 9K，从这里我们可以得出一个结论。就是JDK里的工具几乎是用Java所编写，所以也是Java应用程序，因此要使用JDK所附的工具来开发Java程序，也必须要自行附一套JRE才行，所以位于C:\Program Files\Java目录下的那套JRE就是用来运行一般Java程序用的。 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、如果一台电脑安装两套以上的JRE，谁来决定呢？这个重大任务就落在java.exe身上。Java.exe的工作就是找到合适的JRE来运行Java程序。 Java.exe依照底下的顺序来查找JRE：自己的目录下有没有JRE；父目录有没有JRE；查询注册表： [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment] 所以java.exe的运行结果与你的电脑里面哪个JRE被执行有很大的关系。 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; 3、介绍JVM JRE目录下的Bin目录有两个目录：server与client。这就是真正的jvm.dll所在。 jvm.dll无法单独工作，当jvm.dll启动后，会使用explicit的方法（就是使用Win32 API之中的LoadLibrary()与GetProcAddress()来载入辅助用的动态链接库），而这些辅助用的动态链接库（.dll）都必须位于jvm.dll所在目录的父目录之中。因此想使用哪个JVM，只需要设置PATH，指向JRE所在目录底下的jvm.dll</p>
 <img src ="http://www.blogjava.net/tianmaoye/aggbug/205617.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tianmaoye/" target="_blank">飞行鱼</a> 2008-06-03 17:56 <a href="http://www.blogjava.net/tianmaoye/articles/205617.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>