[Java学习日志]关于字符串的二三事
2016-07-05 22:20
274 查看
今天谈下字符串。
众所周知,字符串操作是计算机编程中最常见的操作,我们无时无刻不在和字符串打交道,因此了解字符串的一些行为对编程有巨大的好处。
顾名思义,可变类指的是你可以改变该类的实例的内容,而不可变类即你不可以改变该类的实例的内容。
如:int i = 1; 我们可以改变整形变量i的内容,如使i = 2;
而如果有一个字符串,如String s = "Hello,world!"。其实,我们看似可以进行改变字符串内容的行为,如s = "Hello,again"。然而事实上我们知道,s其实为一个String类型的引用上诉看似改变其内容的行为事实上是再创建了一个叫做"Hello,again"的新字符串,然后将String类型引用s从"Hello,world!"上重新指向了该新字符串,并非是改变了字符串的内容,然后没有引用指向的字符串"Hello,world!"由Java垃圾处理机制处理。
在Java中,String类型属于不可变类,其对象是不可变的。其实当你查看Java源代码时就会发现,对于String类中的每一个看似修改其内容改的方法,实际上都是再创建了一个新的String对象,然后包含修改后的字符串内容。
如:下面是String类中连接字符串的concat方法源码:
在Java中的可变类有如全部的基本类型,不可变类有如String类,基本类型的包装类等。
以上是关于字符串的一些基本内部原理。
+号操作时间:11587
concat号操作时间:15
StringBuffer append操作时间:8
可以看到不同的方法拥有不同性能。
之前提到过String为不可变类,故其一些改变看似改变内容的方法操作实际上是创建了新的String类。而对于字符串连接操作,其内部实现也许使用的是列表也许使用了链表,由于各自采用算法的时间,空间复杂度不同,所以导致了性能差异。
不同的性能在实现应用复杂的功能时可能会带来一定影响。
<
81d6
span style="font-size:18px;">
以上便是在学习字符串时的一些了解和分享,若有不足,错误之处,望能给予指出批评。
众所周知,字符串操作是计算机编程中最常见的操作,我们无时无刻不在和字符串打交道,因此了解字符串的一些行为对编程有巨大的好处。
一、不可变类.
首先我们从Java的可变类与不可变类开始。那么什么是可变类,什么是不可变类呢?顾名思义,可变类指的是你可以改变该类的实例的内容,而不可变类即你不可以改变该类的实例的内容。
如:int i = 1; 我们可以改变整形变量i的内容,如使i = 2;
而如果有一个字符串,如String s = "Hello,world!"。其实,我们看似可以进行改变字符串内容的行为,如s = "Hello,again"。然而事实上我们知道,s其实为一个String类型的引用上诉看似改变其内容的行为事实上是再创建了一个叫做"Hello,again"的新字符串,然后将String类型引用s从"Hello,world!"上重新指向了该新字符串,并非是改变了字符串的内容,然后没有引用指向的字符串"Hello,world!"由Java垃圾处理机制处理。
在Java中,String类型属于不可变类,其对象是不可变的。其实当你查看Java源代码时就会发现,对于String类中的每一个看似修改其内容改的方法,实际上都是再创建了一个新的String对象,然后包含修改后的字符串内容。
如:下面是String类中连接字符串的concat方法源码:
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true); }可以看到连接字符串的操作实际上也是再创建了一个新的字符串,在包含修改后的内容。
在Java中的可变类有如全部的基本类型,不可变类有如String类,基本类型的包装类等。
以上是关于字符串的一些基本内部原理。
二、关于字符串的一些操作的性能测试
下面进行了对于字符串的+号连接操作,concat方法连接操作,StringBuffer的append操作测试:<span style="white-space:pre"> </span>String s1 = "abc"; String s2 = "def"; long start = System.currentTimeMillis(); for(int i = 0; i < 100000; i++){ s1 += s2; } long end = System.currentTimeMillis(); long result = end - start; System.out.println("+号操作时间:"+result); s1 = "abc"; start = System.currentTimeMillis(); for(int i = 0; i < 100000; i++){ s1.concat(s2); } end = System.currentTimeMillis(); result = end - start; System.out.println("concat号操作时间:"+result); StringBuffer str = new StringBuffer("abc"); start = System.currentTimeMillis(); for(int i = 0; i < 100000; i++){ str.append("def"); } str.toString(); end = System.currentTimeMillis(); result = end - start; System.out.println("StringBuffer append操作时间:"+result);得出结果为:
+号操作时间:11587
concat号操作时间:15
StringBuffer append操作时间:8
可以看到不同的方法拥有不同性能。
之前提到过String为不可变类,故其一些改变看似改变内容的方法操作实际上是创建了新的String类。而对于字符串连接操作,其内部实现也许使用的是列表也许使用了链表,由于各自采用算法的时间,空间复杂度不同,所以导致了性能差异。
不同的性能在实现应用复杂的功能时可能会带来一定影响。
<
81d6
span style="font-size:18px;">
以上便是在学习字符串时的一些了解和分享,若有不足,错误之处,望能给予指出批评。
相关文章推荐
- spring学习(三)—AOP
- Java基础知识(一)
- 反人类的MyEclipse之-eclipse设置花括号换行显示
- Spring之AOP专题报道(自己总结版)
- Redkale RESTful 插件介绍
- JAVA并发编程的艺术目录
- java 冒泡排序算法
- 《深入理解Java集合框架》系列文章
- Java的反射解析
- Struts源码分析1
- RxJava 事件流之转换数据流
- shiro springmvc 注解 ajax和同步请求 无权限处理处理
- java 对象之间属性值复制
- 【Java进阶七】内部类
- Java Date和MySQL datetime数据类型转换
- Java如何判断线程池所有任务是否执行完毕
- 问题: Cannot change version of project facet Dynamic Web Module to 2.5.
- JAVA中的关键字
- [无异常,才正常]java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
- java.lang.InterruptedException: sleep interrupted异常