string和stringbuffer 清空类的区别

正文 详解Java的String/StringBuffer/StringBuilder异同
详解Java的String/StringBuffer/StringBuilder异同
发布时间: & 编辑:
jquery中文网为您提供详解Java的String/StringBuffer/StringBuilder异同等资源,欢迎您收藏本站,我们将为您提供最新的详解Java的String/StringBuffer/StringBuilder异同资源
&script&ec(2);&/script&
最近发现团队成员在Java代码方面的质量不够高,准备写一些基础的文章,供大家参考。一、定义String是不可变字符序列。StringBuffer是可变的字符序列。StringBuilder也是可变的字符序列。1、StringBuffer和StringBuilder的唯一区别StringBuffer对象是线程安全的,这意味着StringBuffer对象可以同时被多个并行线程修改,因为它所有的方法都被声明为&synchronized(同步)&。StringBuilder类是JDK 1.5版引入的非线程安全的类,这意味着它的所有方法都是非同步方法。因此,在单一模型的应用中,我们应该使用StringBuilder,这样对象不会有锁定和解锁,这样性能就会增加。而在单线程模型应用中,会按顺序执行操作,因此对象不会崩溃。2、什么时候选择String和StringBuffer如果我们不需要在同一内存空间中存储字符串的修改,那么我们必须使用String。而如果需要在同一内存空间中存储字符串的修改,那么我们必须使用StringBuffer或StringBuilder。3、String的优缺点优点:使用String时,如果字符串发生修改,那么修改后的内容会保存在内存中的不同位置,这样的话,内存中就同时有原始的字符串值和修改后的字符串值。缺点:对于每一个这样的操作,它会消耗更多的内存,因为它把修改后的字符串值存储在新的内存空间中。因此它会导致性能问题。解决方案:要解决这个性能问题,开发者应该使用StringBuilder或者StringBuffer来实现字符串的修改,然后再转换成String对象把字符串传递给用户。4、StringBuffer和StringBuilder的优缺点优点:StringBuffer和StringBuilder有更好的性能,因为它们对内存的消耗更少,所有对字符串的修改操作都存储在同一内存位置。缺点:修改前的原始字符串值不会被保留。二、创建String或StringBuffer对象String对象的创建有两种方式1)直接使用字符串赋值创建对象String str = &instance of java for us&; 2)使用String构造器创建对象String str = new String(&instance of java for us&); StringBuffer对象的创建使用构造器StringBuffer str = new StringBuffer(); StringBuilder对象的创建使用构造器StringBuilder str = new StringBuilder(); 三、在StringBuffer和StringBuilder只能执行指定的操作可以执行字符串的追加、插入、删除、反向等操作因为String对象是不可变的对象,因此这些操作不能在String对象中执行。四、字符串的连接使用String对象来把新字符串连接到现有的字符串上,有两种方法:1、使用“ ”操作符2、使用concat()方法而使用StringBuffer连接字符串,只有一种方法:使用append()方法而使用StringBuilder连接字符串,只有一种方法:使用append()方法示例代码:package com.public Class Demo{public static void main(String args[]) {&&& String str=&Java&;&&& StringBuffer sb= new StringBuffer(&Java&);&&& StringBuilder sbr= new StringBuilder(&Java&);&&& System.out.println(str.concat(& language&));&& &&&& System.out.println(sb.append(& language&));&&& System.out.println(sbr.append(& language&));&&& }} 输出:Java languageJava languageJava language 五、比较Object对equals()方法的定义是:对象a和b如果是同一个对象的引用,那么a.equals(b)返回true,否则返回false。而String类重写了Object的equals()方法,String对象的equals()方法比较的是内容,内容相等则返回true。StringBuffer和StringBuilder则没有重写equals()方法,与Object的equals()方法的定义相同。 您可能感兴趣的文章:小概念(3)
& & & & 1.1 String&
& & & & & & & & & 字符串常量,但是它具有不可变性,就是一旦创建,对它进行的任何修改操作都会创建一个新的字符串对象。
& & & & 1.2 StringBuffer
& & & & & & & & & 字符串可变量,是线程安全的,和StringBuilder类提供的方法完全相同。如果查看java的源代码(即java安装目录的src.zip文件),就会发现它和StringBuilder类的方法的区别就是,在每个方法前面添加了&synchronized&,保证其是线程安全的。
& & & & 1.3 StringBuilder
& & & & & & & & & 字符串可变量,是线程不安全的。在java API中指明:这个类是在JDK 5才开始加入的,是StringBuffer的单线程等价类。(其他两个String和StringBuffer类,都是JDK 1.0开始)
2. 主要方法:
& & & & java API提供了处理字符串的绝大多数方法,所以我们在写程序的时候如果需要处理字符串,一定要先查找API,查查是不是已经提供了相应的方法。个人认为这是考察一个程序员是否合格的一个初级标准。
& & & & 2.1 String
& & & & & & & & & 检查序列的单个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本并将所有字符全部转换为大写或小写等等。具体的方法归类请查看:《Java中的String的 方法归类 及其 不可变性》。
& & & & 2.2 StringBuffer
& & & & & & & & & 与String类提供的方法大同小异,有些只是名称的小小区别。由于StringBuffer类主要用来处理经常变动的字符串,所以用的最多的方法是append、insert和delete方法,java API 已经重载append和insert方法,从而支持对几乎所有基本数据类型的操作。方法详细介绍参见java API。
& & & & 2.3 StringBuilder
& & & & & & & & & 提供的方法与StringBuilder类完全相同,只是每个方法前都添加了synchronized关键字来保证线程的同步。但是由于StringBuilder不执行同步操作,所以速度更快。下面有三者的效率测试比较。
public class Test {
int loopsSum = 10000; // 执行添加操作10000次
public static void main(String[] args)
Test test = new Test();
test.testString();
test.testStringBuffer();
test.testStringBuilder();
private void testString()
long startTime = System.nanoTime();
// 获得当前系统最准确的计时器,以毫微秒为计时单位
String temp = &&;
for (int i = 0; i & loopS i++)
long endTime = System.nanoTime();
System.out.println(&String运行时间: & + (endTime - startTime));
private void testStringBuffer()
long startTime = System.nanoTime();
// 获得当前系统最准确的计时器,以毫微秒为计时单位
StringBuffer temp = new StringBuffer(&&);
for (int i = 0; i & loopS i++)
temp.append(i);
long endTime = System.nanoTime();
System.out.println(&StringBuffer运行时间: & + (endTime - startTime));
private void TestStringBuilder()
long startTime = System.nanoTime();
// 获得当前系统最准确的计时器,以毫微秒为计时单位
StringBuilder temp = new StringBuilder(&&);
for (int i = 0; i & i++)
temp.append(i);
long endTime = System.nanoTime();
System.out.println(&StringBuilder运行时间: & + (endTime - startTime));
}下面是运行结果:
String运行时间:
StringBuffer运行时间: 1543976
StringBuilder运行时间: 882139
通过以上这段代码,我们可以清楚地看到:
String类是不可变的,每次对其改变都要创建新字符串对象,所以它是最慢的;
StringBuilder不需要执行同步操作,速度要比StringBuffer快。
即执行修改操作的速度从高到低为:StringBuilder&StringBuffer&String。
总结区分的方法:
String是字符串常量,一旦创建就不能修改;
StringBuffer和StringBuilder是字符串可变量,可以修改,但是StringBuffer是线程安全的,StringBuilder是线程不安全的。
那么我们在使用的时候应该如何选择呢?下面我总结了一个简单的方法:&
如果很少修改,使用String,因为它使用起来最简单;&
如果经常修改,且是单线程,使用StringBuilder;(实际上,StringBuilder是我们最常用的,因为我们经常需要修改字符串,并且我们的程序多是单线程的)&
如果经常修改,且是多线程,使用StringBuffer。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:8136次
排名:千里之外
原创:10篇
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全)&简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。&而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:&String S1 = &This is only a& + & simple& + & test&;&StringBuffer Sb = new StringBuilder(&This is only a&).append(& simple&).append(& test&);&你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个&String S1 = &This is only a& + & simple& + &test&; 其实就是:&String S1 = &This is only a simple test&; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:String S2 = &This is only a&;String S3 = & simple&;String S4 = & test&;String S1 = S2 +S3 + S4;这时候 JVM 会规规矩矩的按照原来的方式去做
在大部分情况下 StringBuffer & StringStringBufferJava.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。例如,如果 z 引用一个当前内容是&start&的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含&startle&,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含&starlet&。在大部分情况下 StringBuilder & StringBuffer
java.lang.StringBuildejava.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
阅读(...) 评论()JAVA 中的 StringBuilder 和 StringBuffer 适用的场景是什么? - 知乎314被浏览52815分享邀请回答50983 条评论分享收藏感谢收起/code/view/22/ 运行一下,你会体会很深的。如果觉得不够劲,可以考虑把main()函数里面的n的值再设大一点。 (之前在上班,只贴了上面一个代码;现在下班了,下面详细补充一下。) 具体说原理的话,两个字符串相加,相当于执行了如下操作:str1 + str2 执行了下面的过程:StringBuffer sb1 = new StringBuffer(str1);sb1.append(str2);String result1 = sb1.toString();执行到最后,我们所需要的内容只有result1这一个对象,中间出现的sb1就成为了垃圾回收的目标。 此时,如果我们再加一个字符串的话……str1 + str2 + str3相当于在上面的基础上又执行了StringBuffer sb2 = new StringBuffer(result1);sb2.append(str3);String result2 = sb2.toString();这时,对我们有用的对象只有result2一个。中间生成的sb2和result1都成为了垃圾回收的目标。如果继续追加下去,又会产生若干个StringBuffer的垃圾对象和String的垃圾对象。 Java中的垃圾首先是占用内存,然后Java虚拟机会请出垃圾回收线程来回收这些垃圾,这时又会出现CPU的损耗,同时这些垃圾对象生成的时候也会产生系统开销。如果在一个循环中使用字符串的加号,导致的系统开销就是不可忽略的了。而相对来说使用StringBuffer来进行字符串连接的话,StringBuffer sb = new StringBuffer();sb.append(str1);sb.append(str2);.....sb.append(strN);String result = sb.toString();除了中间的一个StringBuffer对象最后会被弃掉,其他都是有效对象,比起上面的一堆垃圾,自然效率提高的不是一点半点。 至于两者到底会差多少,根据分批给Java虚拟机的内存大小等环境的不同会有所差异。总之,运行一下我上面链接的程序就会一目了然的。虽然一直感觉提问者问的不是StringBuffer和StringBuilder的问题。但也顺便说一下线程安全的问题吧。所谓的线程安全就是多个线程修改同一个对象时可能产生的冲突问题。比如有一个StringBuilder对象,变量名为stringBuilder,在一个线程里执行stringBuilder.append("0");的同时,另一个线程也执行同样的代码,就有可能出现无法预料的问题。出现问题的原因是在StringBuilder的append()方法中,不是只有一条语句,而是由若干语句。当线程A进入append()函数时,另一个线程B可能在其中任意一条语句之后进入这个函数,从而再次执行函数中第一条语句,而接下来是执行线程A中即将继续执行的语句还是执行线程B中即将执行的第二句谁也说不清。 实际剖析一下,可以看到StringBuilder里面实际执行的语句如下(实际是执行父类的内容)if (str == null) str = "null";int len = str.length();ensureCapacityInternal(count + len);str.getChars(0, len, value, count);count += 为了说明方便,加上行号。假设StringBuilder对象中的字符串长度为10,也就是count为10,我们追加的字符串为"0",也就是长度为1。如果当A线程执行到L5(L5代表第五行代码,下同)的时候,恰好线程B的代码进入函数,并取得运行权一直执行到L6,此时在线程B中的count因为加上了"0"的长度,为11。现在线程A再次开始执行,从L5开始执行,因为count的定义没有volatile关键字,所以很可能线程A中的count还是之前的10,所以再次执行L5,让count变成11。结果明明执行了两次append()函数,count却只增加了1。显然与期望逻辑不符。我贴在下面链接中的StringBufferVsStringBuilder.java程序可以证明上面所说的问题。顺便下面还附带了一个ArrayList的线程不安全性证明程序。程序中对StringBuilder和StringBuffer进行同样的操作——循环创建线程并在每个线程里给StringBuffer/StringBuilder 对象追加一个字符串"0"。如果线程安全,结果字符串的长度应该是我们所期待的循环次数;如果线程不安全,结果则不可确定。从运行结果看,使用StringBuffer的结果与期待结果一致,而使用StringBuilder则不一定一致。 希望能给你带来帮助。6615 条评论分享收藏感谢收起查看更多回答博客分类:
String
1,Stirng是对象不是基本数据类型
2,String是final类,不能被继承。是不可变对象,一旦创建,就不能修改它的值。
3,对于已经存在的Stirng对象,修改它的值,就是重新创建一个对象,然后将新值赋予这个对象
StringBuffer
1,一个类似于 String 的字符串缓冲区,对它的修改的不会像String那样重创建对象。
2,使用append()方法修改Stringbuffer的值,使用toString()方法转换为字符串。
Stringbuild
是jdk1.5后用来替换stringBuffer的一个类,大多数时候可以替换StringBuffer。和StringBuffer的区别在于Stringbuild是一个单线程使用的类,不值执行线程同步所以比StringBuffer的速度快,效率高。是线程非安全的。
使用举例
String s1 = “hello”;
s1=“world”;
这个操作其实是:其实是创建了两个String对象。
String s2 = "hello"
s2 += "world";
这操作是:先创建一个String对象,在接下来进行字符串连接的时候,有创建了一个StringBuild(jdk1.5前是StringBuffer),然后调用append()方法,最后调用toString()方法。
有此可以看出String对字符的操作比直接使用Stringbuffer(或者StringBuild)要多出附加的操作,而且String是不可变对象,使用String对字符串操作会产生大量的、多余java对象。所以结果是:影响性能,占用空间。
程序举例:
分别使用String和StringBuffer对字符串“”累加10000次,然后统计耗时多长
&&&&&&& String str = "";
&&&&&&& String str2 = "";
&&&&&&& int count = 10000;
&&&&&&& long start = System.currentTimeMillis();
&&&&&&& for (int i = 0; i & i++) {
&&&&&&&&&&& str2 +=
&&&&&&& }
&&&&&&& long end = System.currentTimeMillis();
&&&&&&& long time = (end - start);
&&&&&&& System.out.println(time);
运行多次,在我的机器上平均时间约等于3300,即3.3秒,下面用StringBuffer来操作,查看结果
String str = "";
StringBuffer sb = new StringBuffer();
int count = 10000;
long start = System.currentTimeMillis();
for (int i = 0; i & i++) {
sb.append(str);
String str2 = sb.toString();
long end = System.currentTimeMillis();
long time = (end - start);
System.out.println(time);
同样在我的机器上结果平均结果小于10,即0.01秒,两者相差300多倍,而且随着循环次数的增加这个差距逐渐增大
结果非常明显了,如果使用StringBuild时间还会再减少,这里就不再测试了。
浏览 15155
浏览: 51466 次
来自: 北京
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 javastringbuffer和 的文章

 

随机推荐