黑马程序员 String 与StringBuffer
2012-06-20 15:46
435 查看
----------------------
android培训、java培训、期待与您交流! ----------------------
出于方便的考虑,我们在进行字符串的内容处理的时候往往会出现以下的代码:
String result="";
result+="ok";
这段代码看上去好像没有什么问题,但是需要指出的是其性能很低,原因是java中的String类不可变的(immutable),这段代码实际的工作过程会是如何的呢?通过使用javap工具我们可以知道其实上面的代码在编译成字节码的时候等同的源代码是:
String result="";
StringBuffer temp=new StringBuffer();
temp.append(result);
temp.append("ok");
result=temp.toString();
短短的两个语句怎么呢变成这么多呢?问题的原因就在String类的不可变性上,而java程序为了方便简单的字符串使用方式对+操作符进行了重载,而这个重载的处理可能因此误导很多对java中String的使用。
下面给出一个完整的代码:
public class Perf {
public static String detab1(String s)
{
if (s.indexOf('\t') == -1)
return s;
String res = "";
int len = s.length();
int pos = 0;
int i = 0;
for (; i < len && s.charAt(i) == '\t'; i++)
{
res += " ";
pos += 8;
}
for (; i < len; i++)
{
char c = s.charAt(i);
if (c == '\t') {
do {
res += " ";
pos++;
} while (pos % 8 != 0);
}
else {
res += c;
pos++;
}
}
return res;
}
public static String detab2(String s)
{
if (s.indexOf('\t') == -1)
return s;
StringBuffer sb = new StringBuffer();
int len = s.length();
int pos = 0;
int i = 0;
for (; i < len && s.charAt(i) == '\t'; i++)
{
sb.append(" ");
pos += 8;
}
for (; i < len; i++) {
char c = s.charAt(i);
if (c == '\t') {
do {
sb.append(' ');
pos++;
} while (pos % 8 != 0);
}
else {
sb.append(c);
pos++;
}
}
return sb.toString();
}
public static String testlist[] = {
"",
"\t",
"\t\t\tabc",
"abc\tdef",
"1234567\t8",
"12345678\t9",
"123456789\t"
};
public static void main(String args[])
{
for (int i = 0; i < testlist.length; i++) {
String tc = testlist[i];
if (!detab1(tc).equals(detab2(tc)))
System.err.println(tc);
}
String test_string =
"\t\tthis is a test\tof detabbing performance";
int N = 5000;
int i = 0;
long ct = System.currentTimeMillis();
for (i = 1; i <= N; i++)
detab1(test_string);
long elapsed = System.currentTimeMillis() - ct;
System.out.println("String time = " + elapsed);
ct = System.currentTimeMillis();
for (i = 1; i <= N; i++)
detab2(test_string);
elapsed = System.currentTimeMillis() - ct;
System.out.println("StringBuffer time = "
+ elapsed);
}
}
执行以上代码的结果可以看到使用StringBuffer的版本的方法比使用String版本的一般都快十倍以上(本人使用的是JDK1.4.0),你可以执行一下看看结果到底如何。
因此得到的结论是:如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法好了!也许这就是你的程序的性能瓶颈!
---------------------- android培训、java培训、期待与您交流!
----------------------详细请查看:http://edu.csdn.net/heima
android培训、java培训、期待与您交流! ----------------------
出于方便的考虑,我们在进行字符串的内容处理的时候往往会出现以下的代码:
String result="";
result+="ok";
这段代码看上去好像没有什么问题,但是需要指出的是其性能很低,原因是java中的String类不可变的(immutable),这段代码实际的工作过程会是如何的呢?通过使用javap工具我们可以知道其实上面的代码在编译成字节码的时候等同的源代码是:
String result="";
StringBuffer temp=new StringBuffer();
temp.append(result);
temp.append("ok");
result=temp.toString();
短短的两个语句怎么呢变成这么多呢?问题的原因就在String类的不可变性上,而java程序为了方便简单的字符串使用方式对+操作符进行了重载,而这个重载的处理可能因此误导很多对java中String的使用。
下面给出一个完整的代码:
public class Perf {
public static String detab1(String s)
{
if (s.indexOf('\t') == -1)
return s;
String res = "";
int len = s.length();
int pos = 0;
int i = 0;
for (; i < len && s.charAt(i) == '\t'; i++)
{
res += " ";
pos += 8;
}
for (; i < len; i++)
{
char c = s.charAt(i);
if (c == '\t') {
do {
res += " ";
pos++;
} while (pos % 8 != 0);
}
else {
res += c;
pos++;
}
}
return res;
}
public static String detab2(String s)
{
if (s.indexOf('\t') == -1)
return s;
StringBuffer sb = new StringBuffer();
int len = s.length();
int pos = 0;
int i = 0;
for (; i < len && s.charAt(i) == '\t'; i++)
{
sb.append(" ");
pos += 8;
}
for (; i < len; i++) {
char c = s.charAt(i);
if (c == '\t') {
do {
sb.append(' ');
pos++;
} while (pos % 8 != 0);
}
else {
sb.append(c);
pos++;
}
}
return sb.toString();
}
public static String testlist[] = {
"",
"\t",
"\t\t\tabc",
"abc\tdef",
"1234567\t8",
"12345678\t9",
"123456789\t"
};
public static void main(String args[])
{
for (int i = 0; i < testlist.length; i++) {
String tc = testlist[i];
if (!detab1(tc).equals(detab2(tc)))
System.err.println(tc);
}
String test_string =
"\t\tthis is a test\tof detabbing performance";
int N = 5000;
int i = 0;
long ct = System.currentTimeMillis();
for (i = 1; i <= N; i++)
detab1(test_string);
long elapsed = System.currentTimeMillis() - ct;
System.out.println("String time = " + elapsed);
ct = System.currentTimeMillis();
for (i = 1; i <= N; i++)
detab2(test_string);
elapsed = System.currentTimeMillis() - ct;
System.out.println("StringBuffer time = "
+ elapsed);
}
}
执行以上代码的结果可以看到使用StringBuffer的版本的方法比使用String版本的一般都快十倍以上(本人使用的是JDK1.4.0),你可以执行一下看看结果到底如何。
因此得到的结论是:如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法好了!也许这就是你的程序的性能瓶颈!
---------------------- android培训、java培训、期待与您交流!
----------------------详细请查看:http://edu.csdn.net/heima
相关文章推荐
- (五)黑马程序员——Java中的字符串操作类(String、StringBuilder、StringBuffer)
- 黑马程序员—String、StringBuffer、StringBuilder
- 黑马程序员_java学习笔记之(StringBuider&Stringbuffer)区别
- 黑马程序员——String,StringBuffer和基本数据类型对象包装类
- 黑马程序员——Java基础——String、StringBuffer
- 黑马程序员----论String,StringBuffer,StringBuilder,基本数据类型对象包装类
- 黑马程序员__String_StringBuffer_基本数据类型对象包装类
- 黑马程序员——String、Integer、StringBuffer和API类中的常用方法
- 黑马程序员-----String,StringBuffer,StringBulider
- 黑马程序员_06常用类String 、StringBuffer、File类以及递归调用
- 黑马程序员——String字符串,StringBuilder和StringBuffer,线性表: List,散列表
- 黑马程序员---------笔记整理(java基础九-----String,StringBuffer,StringBuilder)
- 黑马程序员--String、StringBuffer、基本数据类型包装类
- 黑马程序员——包装类,String,StringBuffer
- 【黑马程序员】String和StringBuffer 的区别与应用!
- 黑马程序员----------String,StringBuffer,StringBuilder用法
- 黑马程序员_StringBuffer和StringBuillder和String类
- 黑马程序员------常用类之String和StringBuffer
- 黑马程序员-String与StringBuffer、数值包装类、自动装箱拆箱
- 黑马程序员---String与StringBuffer