String对象
String 对象的创建方式的原理:
当使用任何方式来创建一个字符串对象X时,Java运行时(运行中JVM)会拿着这个X在String池中查找是否存在内容相同的字符串对象,如果不存在,则在池中查找是否存在相同的字符串对象,如果不存在,则在池中创建一个字符串X,否则,不会创建对象,即不会在池中添加。
只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
使用直接指定或者纯字符窗串联来创建sSring对象,则仅仅会检查维护String池中的字符串,池中没有旧创建一个,如果存在,就不创建新的,不会中堆栈区再去创建该String对象。
使用包含该变量的表达式来创建String对象,则不仅会检查并维护String池,而且会在堆栈区创建一个String对象。
String 有三个特点:
不变性
针对常量池的优化
类的final定义
不变性是指String对象一旦生成,则不能再对它进行改变。String的这个特性可以泛化成不变模式,即一个对象的状态中对象被创建后就不再发生变化。不变模式的主要作用在于当一个对象需要被多线程共享,并且访问频繁时,可以省略同步和锁等待的时间,大幅提高系统性能。
String的引用方式对比:
String str1="abc";
String str2="abc";
String str3=new String("abc");
String str4=str1;
str1==str2 true
str1==str3 false
str1.intern()==str3.intern() true
str1==str4 true
str2==str3 true
str4.intern()==str3.intern() true
intern()方法:是一个本地方法,如果常来池已经包含一个等于此String对象的字符串(由equals(Object)判定),则返回池中的字符串。否则,将此String对象添加到池中,并且返回此String对象的引用。
当使用newString去构造一个全新的字符串而不是赋值来创建时,就导致了另外一个潜在的性能问题:重复创建大量相同的字符串。为了解决这个问题,大概有如下两种方法:
使用String的intern()方法返回JAV对字符串缓存池里的字符串应用,但是过多使用intern会导致PermGen(用来存放装载类和实例类是用到的元数据)过度增长而最后返回outofmemoryerror。
用户自己构建缓存,创建hashmap()将需要缓存的String作为key和value存放入HashMap。
关于String的SubString方法
String.substring()所返回的String仍然回包含原始String,如果String.substring截取出了大量String,则可以在很大程度节省内存,如果在一个巨大的String只截取少数String,则会造成大量冗余数据。
改进的方法:构造一个内容相同的新的字符串
str.substring(int start,int end);
改为:
new String(str.substring(int start,int end));
使用改进的方法后,原来由substring方法返回的String就会被回收掉,节省了内存。
关于charat() 和startswith()
如果只是查找单个字符的话,考虑用charat代替startwith
if(s.startwitch("a"){ }
if('a'==s.charat(0)){ }
在字符串相加的时候,用'代替"
字符串切割
处理字符串性能:
substring > StringTokenizer类切割 > split切割
(StringTokenizer类用法 :new StringTokenizer(orgStr,"," ) )
合并字符串
合并字符串性能:
1.
String str="123";
str=str+i;
2.
str=str.concat("123");
3.
StringBuilder sb=new StringBuilder();
sb.append(i);
执行效率
3 > 2 > 1