String,StringBuffer,StringBuilder之间的异同
2017-10-25 09:42
405 查看
一,了解String对象
二,StringBuffer对象与String的区别和好处
三,StringBuilder的优点
我们知道String不是八种基本数据类型,那它是怎么存储字符串的?
我们来看一下源码:
String是final的,不可被继承。并且它创建的对象一旦被创建就不能被改变了(后面给予代码证明)。
里面定义了char数组来存储Value,所以我们知道了,String原来是用char来存储字符串的。
我们都知道String可以有两种方法定义:
String str = “”;
String str = new String (“”);
那么你知道String str = new String(“java”);是创建了几个字符创?
是两个,一个是new String(”),一个是“java”,因为在jvm初始化的时候创建了“java”字符串,然后new 使得String构造函数将str的引用指向new出来新字符创(根据“java”构造出的新字符串)。
猜猜输出什么?
如果你说输出:
java
iava
那你就错了,应该是输出:
java
java
为什么?就是因为String对象是不可变对象,它的所有方法(在原有的字符串上操作)都会产生一个新的对象,所以我们输出的对象依旧是原来的对象。
4000
虽然改变了“原来的对象”,但是原来的对象没变,而是又生成了一个字符创对象。
我们将上面的代码改进一下:
这段代码输出的就是:
old:java
new:iava
(具体为什么产生新的对象,参考String方法源码)
二,接下来我们来看看StringBuffer,和String不同StringBuffer是可变的(它的所有属性不是final的),也就是不像String那样在原有的字符创上更改会产生新的字符串。
我们下面先来看看两段代码的比较:
同样都是添加字符串,StringBuffer的效率是String的1000倍(运算次数越大差距越明显)。就是因为StringBuffer不会创建那么多的对象,而String在改变字符串的同时会浪费大量的时间来创建新的字符串。
总结:String是不可变的,StringBuffer是可变的,且是线程安全的。
三,我们再来看看StringBuilder:
这个家伙是不是似曾相识?
它和StingBuffer几乎相同,都继承了相同的父类实现相同的接口。
初始大小都是16,同样可以自动扩容,但它的方法不带有synchronized的关键字,所以如果是单机,或者不涉及到多线程的操作使用StingBuilder效率更高,若设计到多线程和线程安全则建议使用StringBuffer。
效率:
StringBuilder > StringBuffer > String
当然这个是相对的,不一定在所有情况下都是这样。
比如String str = “hello”+ “world”的效率就比 StringBuilder st = new StringBuilder().append(“hello”).append(“world”)要高。
因此,这三个类是各有利弊,应当根据不同的情况来进行选择使用:
当字符串相加操作或者改动较少的情况下,建议使用 String str=”hello”这种形式;
当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。
二,StringBuffer对象与String的区别和好处
三,StringBuilder的优点
我们知道String不是八种基本数据类型,那它是怎么存储字符串的?
我们来看一下源码:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {}
String是final的,不可被继承。并且它创建的对象一旦被创建就不能被改变了(后面给予代码证明)。
private final char value[];
里面定义了char数组来存储Value,所以我们知道了,String原来是用char来存储字符串的。
我们都知道String可以有两种方法定义:
String str = “”;
String str = new String (“”);
那么你知道String str = new String(“java”);是创建了几个字符创?
是两个,一个是new String(”),一个是“java”,因为在jvm初始化的时候创建了“java”字符串,然后new 使得String构造函数将str的引用指向new出来新字符创(根据“java”构造出的新字符串)。
package testJavaSE; public class testString { public static void change(String text) { text.replace("j", "i"); } public static void main(String[] args) { String str = new String("java"); System.out.println(str); change(str); System.out.println(str); } }
猜猜输出什么?
如果你说输出:
java
iava
那你就错了,应该是输出:
java
java
为什么?就是因为String对象是不可变对象,它的所有方法(在原有的字符串上操作)都会产生一个新的对象,所以我们输出的对象依旧是原来的对象。
4000
虽然改变了“原来的对象”,但是原来的对象没变,而是又生成了一个字符创对象。
我们将上面的代码改进一下:
package testJavaSE; public class testString2 { public static String change(String text) { return text.replace("j","i"); } public static void main(String[] args) { String oldstr = new String("java"); System.out.println("old:"+oldstr); String newstr = change(oldstr); System.out.println("new:"+newstr); } }
这段代码输出的就是:
old:java
new:iava
(具体为什么产生新的对象,参考String方法源码)
二,接下来我们来看看StringBuffer,和String不同StringBuffer是可变的(它的所有属性不是final的),也就是不像String那样在原有的字符创上更改会产生新的字符串。
//StringBuffer的定义 public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence {...}
我们下面先来看看两段代码的比较:
package testJavaSE; public class testString3 { public static void main(String[] args) { String str=""; String tmp="abcdefghijklmnopqrstuvwxyz"; long startTime = System.currentTimeMillis(); for(int i=0;i<10000;i++) { str+=tmp; } long endTime = System.currentTimeMillis(); System.out.println(endTime-startTime); } } //输出:1705(不同的电脑输出不同)
package testJavaSE; public class testStringBuffer { public static void main(String[] args) { StringBuffer str = new StringBuffer(); String tmp="abcdefghijklmnopqrstuvwxyz"; long startTime = System.currentTimeMillis(); for(int i=0;i<10000;i++) { str.append(tmp); } long endTime = System.currentTimeMillis(); System.out.println(endTime-startTime); } } //输出:2
同样都是添加字符串,StringBuffer的效率是String的1000倍(运算次数越大差距越明显)。就是因为StringBuffer不会创建那么多的对象,而String在改变字符串的同时会浪费大量的时间来创建新的字符串。
//StringBuffer也是由char数组来存储数据的 private transient char[] toStringCache; //它的初始化大小为16,如果超出容量,有方法对它扩容 public StringBuffer() { super(16); } //它也可以由我们自己定义数组的大小 public StringBuffer(int capacity) { super(capacity); } //在创建一个StringBuffer的时候,它的大小为传进str大小+16 public StringBuffer(String str) { super(str.length() + 16); append(str); }
public synchronized int length() { return count; } @Override public synchronized int capacity() { return value.length; } @Override public synchronized void ensureCapacity(int minimumCapacity) { super.ensureCapacity(minimumCapacity); } /** * @since 1.5 */ @Override public synchronized void trimToSize() { super.trimToSize(); } /** * @throws IndexOutOfBoundsException {@inheritDoc} * @see #length() */ @Override public synchronized void setLength(int newLength) { toStringCache = null; super.setLength(newLength); } /** * @throws IndexOutOfBoundsException {@inheritDoc} * @see #length() */ @Override public synchronized char charAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; } . . . . . //它的方法都是带有synchronized关键字的所以它是线程安全的。
总结:String是不可变的,StringBuffer是可变的,且是线程安全的。
三,我们再来看看StringBuilder:
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence {..}
这个家伙是不是似曾相识?
它和StingBuffer几乎相同,都继承了相同的父类实现相同的接口。
初始大小都是16,同样可以自动扩容,但它的方法不带有synchronized的关键字,所以如果是单机,或者不涉及到多线程的操作使用StingBuilder效率更高,若设计到多线程和线程安全则建议使用StringBuffer。
效率:
StringBuilder > StringBuffer > String
当然这个是相对的,不一定在所有情况下都是这样。
比如String str = “hello”+ “world”的效率就比 StringBuilder st = new StringBuilder().append(“hello”).append(“world”)要高。
因此,这三个类是各有利弊,应当根据不同的情况来进行选择使用:
当字符串相加操作或者改动较少的情况下,建议使用 String str=”hello”这种形式;
当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。
相关文章推荐
- 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之间区别
- java基础知识回顾---String、StringBuffer与StringBuilder之间区别
- String、StringBuffer与StringBuilder之间区别
- String、StringBuffer与StringBuilder之间区别
- String、StringBuffer与StringBuilder之间区别
- 回首Java——String、StringBuffer与StringBuilder之间区别
- String、StringBuffer与StringBuilder之间区别
- [转]String、StringBuffer与StringBuilder之间区别
- String、StringBuffer与StringBuilder之间区别
- String、StringBuffer与StringBuilder之间区别
- String,StringBuffer与StringBuilder之间的区别
- String、StringBuffer与StringBuilder之间区别