String详解

String 类是非可变类(对象一旦创建了就不能够改变其内在状态了),根据书Effective java中说到,避免创建重复的对象原则。多个引用使用同一个对象而互相不影响。

String S=new String("kill"); 构造函数来创建字符串,如果所创建的字符串在String Pool 中不存在则调用构造函数创建全新的字符串,如果所创建的字符串在字符串缓存池中已有则再拷贝一份到 Java 堆中。总共两个对象。

String s2="kill"; 首先在String Pool池中找(通过equal)有没有kill这个对象,如果有直接把引用指向这个kill对象,如果没有,在heap中创建一个对象(和第一种情况一样),并且把该引用添加到String Pool中。而对第一中情况JVM是不会主动添加到String Pool中去的。


大规模文本分析的案例,实际使用的内存比预估的产生的内存数大的多,主要是在大量使用String.split() 或 String.substring()来操作字符时出现大量的内存消耗。

JDK 1.6 中 String.substring(int, int)的源码为: 

public String substring(int beginIndex, int endIndex) {
	if (beginIndex < 0) {
	    throw new StringIndexOutOfBoundsException(beginIndex);
	}
	if (endIndex > count) {
	    throw new StringIndexOutOfBoundsException(endIndex);
	}
	if (beginIndex > endIndex) {
	    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
	}
	return ((beginIndex == 0) && (endIndex == count)) ? this :
	    new String(offset + beginIndex, endIndex - beginIndex, value);
    }

String.substring()所返回的 String 仍然会保存原始 String。但是JDK String 的源码设计当然有着其合理之处,对于通过 String.split()或 String.substring()截取出大量 String 的操作,这种设计在很多时候可以很大程度的节省内存,因为这些 String 都复用了原始 String,只是通过 int 类型的 start, end 等值来标识每一个 String。

因此有关通过String.split()或 String.substring()截取 String 的操作的结论如下

对于从大文本中截取少量字符串的应用,String.substring()将会导致内存的过度浪费。

对于从一般文本中截取一定数量的字符串,截取的字符串长度总和与原始文本长度相差不大,现有的 String.substring()设计恰好可以共享原始文本从而达到节省内存的目的。


String 优化建议:

在拼接静态字符串时,尽量用 +。

String test = "this " + "is " + "a " + "test " + "string";

在拼接动态字符串时,尽量用 StringBuffer 或 StringBuilder的 append。

使用缓存池的技术来解决string() 带来的内存性能隐患
自己构建缓存,这种方式的优点是更加灵活。创建 HashMap,将需缓存的 String 作为 key 和 value 存放入 HashMap。假设我们准备创建的字符串为 key,将 Map cacheMap 作为缓冲池,那么返回 key 的代码如下:

 private String getCacheWord(String key) { 
     String tmp = cacheMap.get(key); 
     if(tmp != null) { 
            return tmp; 
     } else { 
             cacheMap.put(key, key); 
             return key; 
     } 
 } 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值