Jave String StringBuffer StringBuilder杂想
来源:互联网 发布:python re 匹配域名 编辑:程序博客网 时间:2024/06/15 19:55
记得大学毕业那会,笔试时有这道题,转眼多年过去,不曾在写java, 有点遗憾,现在一点一点的补起来,贵在坚持!
程序性能,除去框架等方面影响等其他影响,剩下就是我们代码写的不聪明,或者说我们没有尽职尽责每一个行代码的深层理解,如上使用,估计大家回使用,但是有没有彻底的深究或者准确使用,如下是自己汇总,便于记录,也便于查看:
首先,查看源码可知,String 声明为: Public final 连接文章详细介绍fianl原理,http://www.importnew.com/7553.html;类似final类还有Interger及其他包装类, 此时不能被继承。同时一旦声明该对象,则不能进行修改,如果修改,则会在内存中重新申请内存来保存新的值,可见如果复杂的字符操作,性能会有差。
为什么设计成为final, Java运行时保存了一个字符串池(String pool),这使得String成为了一个特别的类。这样带来的好处如下:
只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现可以在运行时节约很多heap空间,因为不同的字符串变量都指向池中的同一个字符串。但如果字符串是可变的,那么String interning将不能实现(译者注:String interning是指对不同的字符串仅仅只保存一个,即不会保存多个相同的字符串。),因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。
如果字符串是可变的,那么会引起很严重的安全问题。譬如,数据库的用户名、密码都是以字符串的形式传入来获得数据库的连接,或者在socket编程中,主机名和端口都是以字符串的形式传入。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符串指向的对象的值,造成安全漏洞。
因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。
类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。譬如你想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,那么会对你的数据库造成不可知的破坏。
因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
其次: StringBuffer和StringBuilder都集成了AbstractStringBuilder,而StringBuffer大部分方法都是synchronized,也就是线程安全的,而StringBuilder就没有,所以,我们查看API可以知道,StringBuilder可以操作StringBuffer,但是StringBuffer不可以操作StringBuilder,这也是线程的原因;
可想而知,StringBuffer的效率肯定没有StringBuilder,因为StringBuffer要维持同步锁,这肯定要消耗部分资源,所以三者性能顺序为:StringBuilder>StringBuffer>String
实际使用中主要如下:
首先, String “==” 和equals的区别, 其中 后者主要用于判断两个变量是否是对同一个对象的引用,即堆中的内容是否相同, 前者主要应用于如下:
1, 用于基本数据类型的比较; 2,判断引用是否指向堆内存的同一块地址。
如下例句:
"例子一:对象不同,内容相同,"=="返回false,equals返回true
String strData = new String("data");
String strDataEx = new String("data");
System.out.println(strData ==strDataEx ); // 引用不同, 所以为false
System.out.println(strData .equals(strDataEx )); // 内容相同, 所以为ture
String strData = new String("data");
String strDataEx = strData ;
System.out.println(strData==strDataEx); //应用相同
System.out.println(strData.equals(strDataEx)); //内容相同
String strData = "strData ";
String strDataEx = "strData ";
System.out.println(strData==strDataEx); //true
System.out.println(strData.equals(strDataEx)); //true
注意String 缓冲池:
String缓冲池内不存在与其指定值相同的String对象,那么此时虚拟机将为此创建新的String对象,并存放在String缓冲池内。
String缓冲池内存在与其指定值相同的String对象,那么此时虚拟机将不为此创建新的String对象,而直接返回已存在的String对象的引用。
同时需要明白JVM 常量池的用法, 详见连接http://www.cnblogs.com/xrq730/p/4827590.html;
其次, StringBuilder和StringBuffer使用注意事项, 两者字符串长度均可扩展, StringBuffer是线程安全, StringBuilder是非线程安全的, 其中其是如何动态扩展长度的呢?
如下源码:
public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}
void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) { //// 此处如果新增的长度溢出,则小于0 ,足见写代码的严谨性
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
可见其原理和STL vector 增长机制一样, 由此可见有些思想是大家共识的;
开发中利用StringBuffer和StringBuilder拼接字符串, 其中主要原因如下:
String strTemp = "中国"; //常量池中,没有“中国”, 则创建并指向该值
strTemp += "是" //常量池中,没有“中国是”, 则创建并指向该值
strTemp +="伟大的民族!" 常量池中,没有“中国是伟大的民族”, 则创建并指向该值
通过以上,则发现,其会产生大量的中间临时对象,消耗内存空间,如果复杂的操作中,会造成严重的性能问题, 同时
String strTemp = "中国" + "是" + "伟大的民族!" 这样写虽无过程对象产生,但是代码可读性比较差 ,建议不要这样写!
StringBuilder sbTemp = new StringBuilder("中国");
sbTemp.append("是");
sbTemp.append("伟大的民族!");
此处逻辑为:
StringBuffer和StringBuilder原理一样,无非是在底层维护了一个char数组,每次append的时候就往char数组里面放字符而已,在最终sb.toString()的时候,用一个new String()方法把char数组里面的内容都转成String,这样,常量池中创建了一个最终产生的String,在需要对字符串进行拼接尤其是大量拼接的地方,大量地节省常量池的空间。
- Jave String StringBuffer StringBuilder杂想
- String 、StringBuffer 和 StringBuilder
- String,StringBuffer,StringBuilder(转载)
- String、StringBuffer和StringBuilder
- String,StringBuffer,StringBuilder
- String、StringBuffer和StringBuilder
- String、StringBuffer和StringBuilder
- String StringBuffer StringBuilder
- String StringBuffer StringBuilder
- String StringBuffer StringBuilder
- String StringBuffer StringBuilder
- String ,StringBuffer ,StringBuilder问题
- String StringBuffer StringBuilder
- String StringBuffer StringBuilder 区别
- StringBuilder StringBuffer String
- StringBuilder。StringBuffer。String
- String,StringBuffer与StringBuilder
- String、StringBuffer和StringBuilder
- 手把手教myeclispe Tomcat中add Deployment时deploy location跟Project不一样
- 数据库查询优化策略
- 使用protobuf作为http通讯格式
- ViewGroup的触摸事件的传递源码详细解析
- android 清理进程数据
- Jave String StringBuffer StringBuilder杂想
- Python切片操作
- ssm用ehcache会出现的错误
- spring中bean的作用域
- python学习之路——函数参数问题
- ggplot2学习
- 浅谈JavaScript对象数组根据某属性sort升降序排序
- 解读机器学习基础概念:VC维的来龙去脉
- "viewport" content="width=device-width