java中stringbuffer,java中字符串的是什么?
java中stringbuffer,java中字符串的是什么?详细介绍
本文目录一览: 深入理解String、StringBuffer和StringBuilder类的区别
Java提供了String、StringBuffer和StringBuilder类来封装字符串,并提供了一系列操作字符串对象的方法。
它们的相同点是都用来封装字符串;都实现了CharSequence接口。它们之间的区别如下:
一、可变与不可变
String类是一个不可变类,即创建String对象后,该对象中的字符串是不可改变的,直到这个对象被销毁。StringBuffer与StringBuilder都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,是可变类。
由于String是可变类,适合在需要被共享的场合中使用,当一个字符串经常被修改时,最好使用StringBuffer实现。如果用String保存一个经常被修改的字符串,该字符串每次修改时都会创建新的无用的对象,这些无用的对象会被垃圾回收器回收,会影响程序的性能,不建议这么做。
二、初始化方式
当创建String对象时,可以利用构造方法String str = new String("Java")的方式来对其进行初始化,也可以直接用赋值的方式String s = "Java"来初始化。而StringBuffer只能使用构造方法StringBuffer sb = new StringBuffer("hello")的方式初始化。
三、字符串修改方式
String字符串修改方法是首先创建一个StringBuffer,其次调用StringBuffer的append方法,最后调用StringBuffer的toString()方法把结果返回,示例代码如下:
String str = "hello";
str += "java";
以上代码等价于下面的代码:
StringBuffer sb = new StringBuffer(str);
sb.append("java");
str = sb.toString();
上述String字符串的修改过程要比StringBuffer多一些额外操作,会增加一些临时的对象,从而导致程序的执行效率降低。StringBuffer和StringBuilder在修改字符串方面比String的性能要高。
四、是否实现了equals和hashCode方法
String实现了equals()方法和hashCode()方法,new String("java").equals(new String("java"))的结果为true;
而StringBuffer没有实现equals()方法和hashCode()方法,因此,new StringBuffer("java").equals(new StringBuffer("java"))的结果为false,将StringBuffer对象存储进Java集合类中会出现问题。
五、是否线程安全
StringBuffer与StringBuilder都提供了一系列插入、追加、改变字符串里的字符序列的方法,它们的用法基本相同,只是StringBuilder是线程不安全的,StringBuffer是线程安全的,。如果只是在单线程中使用字符串缓冲区,则StringBuilder的效率会高些,但是当多线程访问时,最好使用StringBuffer。
综上,在执行效率方面,StringBuilder最高,StringBuffer次之,String最低,对于这种情况,一般而言,如果要操作的数量比较小,应优先使用String类;如果是在单线程下操作大量数据,应优先使用StringBuilder类;如果是在多线程下操作大量数据,应优先使用StringBuilder类。
Java中StringBuffer类append方法的使用
Java中append方法的作用是在一个StringBuffer对象后面追加字符串。
例如StringBuffer s = new StringBuffer("Hello");s.append("World");
则s的内容是HelloWorld。
“拓展资料”:
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
参考资料:Java StringBuffer--菜鸟教程
Java程序的性能优化StringBuffer与Vector
Java使得复杂应用的开发变得相对简单 毫无疑问 它的这种易用性对Java的大范围流行功不可没 然而 这种易用性实际上是一把双刃剑 一个设计良好的Java程序 性能表现往往不如一个同样设计良好的C++程序 在Java程序中 性能问题的大部分原因并不在于Java语言 而是在于程序本身 养成好的代码编写习惯非常重要 比如正确地 巧妙地运用java lang String类和java util Vector类 它能够显著地提高程序的性能 下面我们就来具体地分析一下这方面的问题 在java中 使用最频繁 同时也是滥用最多的一个类或许就是java lang String 它也是导致代码性能低下最主要的原因之一 请考虑下面这个例子
String s = Testing String ;String s = Concatenation Performance ;String s = s + + s ;
几乎所有的Java程序员都知道上面的代码效率不高 那么 我们应该怎么办 呢?也许可以试试下面这种代码
StringBuffer s = new StringBuffer();s append( Testing String );s append( );s append( Concatenation Performance );String s = s toString();
这些代码会比第一个代码片段效率更高吗?答案是否定的 这里的代码实际上正是编译器编译第一个代码片段之后的结果 既然与使用多个独立的String对象相比 StringBuffer并没有使代码有任何效率上的提高 那为什么有那么多Java书籍批评第一种方法 推荐使用第二种方法?
第二个代码片段用到了StringBuffer类(编译器在第一个片段中也将使用StringBuffer类) 我们来分析一下StringBuffer类的默认构造函数 下面是它的代码
public StringBuffer() { this( ); }
默认构造函数预设了 个字符的缓存容量 现在我们再来看看StringBuffer类的append()方法
public synchronized StringBuffer append(String str) {if (str == null) { str = String valueOf(str); } int len = str length(); int newcount = count + len; if (newcount > value length) expandCapacity(newcount); str getChars( len value count); count = newcount; return this;}
append()方法首先计算字符串追加完成后的总长度 如果这个总长度大于StringBuffer的存储能力 append()方法调用私有的expandCapacity()方法 expandCapacity()方法在每次被调用时使StringBuffer存储能力加倍 并把现有的字符数组内容复制到新的存储空间
在第二个代码片段中(以及在第一个代码片段的编译结果中) 由于字符串追加操作的最后结果是 Testing String Concatenation Performance 它有 个字符 StringBuffer的存储能力必须扩展两次 从而导致了两次代价昂贵的复制操作 因此 我们至少有一点可以做得比编译器更好 这就是分配一个初始存储容量大于或者等于 个字符的StringBuffer 如下所示
StringBuffer s = new StringBuffer( );s append( Testing String );s append( );s append( Concatenation Performance );String s = s toString();
再考虑下面这个例子
String s = ;int sum = ;for(int I= ; I< ; I++) { sum += I; s = s + + +I ; }s = s + = + sum;
分析一下为何前面的代码比下面的代码效率低
StringBuffer *** = new StringBuffer();int sum = ; for(int I= ; I< ; I++){ sum + = I; *** append(I) append( + ); }String s = *** append( = ) append(sum) toString();
原因就在于每个s = s + + + I操作都要创建并拆除一个StringBuffer对象以及一个String 对象 这完全是一种浪费 而在第二个例子中我们避免了这种情况
我们再来看看另外一个常用的Java类——java util Vector 简单地说 一个Vector就是一个java lang Object实例的数组 Vector与数组相似 它的元素可以通过整数形式的索引访问 但是 Vector类型的对象在创建之后 对象的大小能够根据元素的增加或者删除而扩展 缩小 请考虑下面这个向Vector加入元素的例子
Object obj = new Object();Vector v = new Vector( );for(int I= ; I< ; I++) { v add( obj); }
除非有绝对充足的理由要求每次都把新元素插入到Vector的前面 否则上面的代码对性能不利 在默认构造函数中 Vector的初始存储能力是 个元素 如果新元素加入时存储能力不足 则以后存储能力每次加倍 Vector类就象StringBuffer类一样 每次扩展存储能力时 所有现有的元素都要复制到新的存储空间之中 下面的代码片段要比前面的例子快几个数量级
Object obj = new Object();Vector v = new Vector( );for(int I= ; I< ; I++) { v add(obj); }
同样的规则也适用于Vector类的remove()方法 由于Vector中各个元素之间不能含有 空隙 删除除最后一个元素之外的任意其他元素都导致被删除元素之后的元素向前移动 也就是说 从Vector删除最后一个元素要比删除第一个元素 开销 低好几倍
假设要从前面的Vector删除所有元素 我们可以使用这种代码
for(int I= ; I< ; I++){ v remove( ); }
但是 与下面的代码相比 前面的代码要慢几个数量级
for(int I= ; I< ; I++){ v remove(v size() ); }
从Vector类型的对象v删除所有元素的最好方法是
v removeAllElements();
假设Vector类型的对象v包含字符串 Hello 考虑下面的代码 它要从这个Vector中删除 Hello 字符串
String s = Hello ; int i = v indexOf(s); if(I != ) v remove(s);
这些代码看起来没什么错误 但它同样对性能不利 在这段代码中 indexOf()方法对v进行顺序搜索寻找字符串 Hello remove(s)方法也要进行同样的顺序搜索 改进之后的版本是
String s = Hello ; int i = v indexOf(s); if(I != ) v remove(i);
这个版本中我们直接在remove()方法中给出待删除元素的精确索引位置 从而避免了第二次搜索 一个更好的版本是
String s = Hello ; v remove(s);
最后 我们再来看一个有关Vector类的代码片段
for(int I= ; I
<v size(); i+="){} 如果v包含" 个元素 这个代码片段将调用v size()方法 次 虽然size方法是一个简单的方法 但它仍旧需要一次方法调用的开销 至少jvm需要为它配置以及清除堆栈环境 在这里 for循环内部的代码不会以任何方式修改vector类型对象v的大小 因此上面的代码最好改写成下面这种形式
int size = v size(); for(int I= ; I
<size; i++){}
lishixinzhi/Article/program/Java/gj/201311/27752
java中字符串的是什么?
Java 字符串类主要有String、StringBuffer、StringBuilder、StringTokenizer
1.字符串类型底层都是使用char数组进行实现.
2.从jdk1.7以后,StringBuffer和StringBuilder均继承自AbstractStringBuilder。
提供的方法基本相似,StringBuffer不提供线程同步,StringBuilder是线程同步的,故StringBuilder效率不如StringBuffer
3.对字符串进行操作时,由于String、StringBuffer、StringBuilder都是由char数组实现的,
类似append的操作都会重新产生一个新char数组,只不过由于StringBuffer和StringBuilder的char数组并不是final的,
所以表现为没有产生新的StringBxxxxx对象,但是内部的char数组value的指向是发生了变化的。
4.对字符串进行操作时,由于String的char数组是final的所以任何对String的操作都会产生一个新的对象,StringBuffer和
StringBuilder可以反推。
5.String字符串连接时底层实现方式
例如:
String s1 = "s1";
String s2 = "s2";
String s3 = s1 + s2
对连接部分进行反编译后得到如下代码
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."
":()V
13: aload_1
14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
java中的字符串是由多个字符组成的一串数据,字符串是常量,一旦被创建就不能改变,这是因为字符串的值是存放在方法区的常量池里面,但是引用可以改变。字符串字面值"ab"也可以看成是一个字符串对象。
Java中String,StringBuilder和StringBuffer的区别
楼上正确。补充说明: 所谓的线程安全问题就是同时有多个线程访问同一个资源时引起的数据混乱问题。StringBuffer是线程安全的,所以当它作为成员变量时不存在线程安全问题。StringBuilder是线程不安全的,在作为成员变量时有可能出现线程不安全问题。如果在方法内部使用一个这样的变量,用StringBuilder效率会更高,因为首先StringBuilder没有加锁,其次方法内部不存在线程安全问题。
1. 在执行速度方面的比较:StringBuilder > StringBuffer
2. StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。
3. StringBuilder:线程非安全的
StringBuffer:线程安全的
当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。
对于三者使用的总结:1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
String 是一个不可变长度的字符串对象
StringBuilder 与 StringBuffer 是可变长度字符串对象
StringBuffer 是线程安全的, StringBuilder 是非线程安全的。
1 String
String:字符串常量,字符串长度不可变。Java中String是immutable(不可变)的。
String类的包含如下定义:
/** The value is used for character storage. */ private final char value[]; /** The offset is the first index of the storage that is used. */ private final int offset; /** The count is the number of characters in the String. */ private final int count;用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。
2 StringBuffer(JDK1.0)
StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用StringBuffer,如果想转成String类型,可以调用StringBuffer的toString()方法。
Java.lang.StringBuffer线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
3 StringBuilder(JDK5.0)
StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder对象被当作是一个包含字符序列的变长数组。
java.lang.StringBuilder是一个可变的字符序列,是JDK5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。
其构造方法如下:
构造方法 描述
StringBuilder() 创建一个容量为16的StringBuilder对象(16个空元素)
StringBuilder(CharSequence cs) 创建一个包含cs的StringBuilder对象,末尾附加16个空元素
StringBuilder(int initCapacity) 创建一个容量为initCapacity的StringBuilder对象
StringBuilder(String s) 创建一个包含s的StringBuilder对象,末尾附加16个空元素
在大部分情况下,StringBuilder > StringBuffer。这主要是由于前者不需要考虑线程安全。
4 三者区别
String 类型和StringBuffer的主要性能区别:String是不可变的对象, 因此在每次对String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
在某些特别情况下, String 对象的字符串拼接其实是被 Java Compiler 编译成了 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慢。其实在Java Compiler里,自动做了如下转换:
Java Compiler直接把上述第一条语句编译为:
String s1 = “This is only a simple test”;
所以速度很快。但要注意的是,如果拼接的字符串来自另外的String对象的话,Java Compiler就不会自动转换了,速度也就没那么快了,例如:
String s2 = “This is only a”;
String s3 = “ simple”;
String s4 = “ test”;
String s1 = s2 + s3 + s4;
这时候,Java Compiler会规规矩矩的按照原来的方式去做,String的concatenation(即+)操作利用了StringBuilder(或StringBuffer)的append方法实现,此时,对于上述情况,若s2,s3,s4采用String定义,拼接时需要额外创建一个StringBuffer(或StringBuilder),之后将StringBuffer转换为String;若采用StringBuffer(或StringBuilder),则不需额外创建StringBuffer。
5 使用策略
(1)基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。
(2)不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。例如:
String result = ""; for (String s : hugeArray) { result = result + s; } // 使用StringBuilder StringBuilder sb = new StringBuilder(); for (String s : hugeArray) { sb.append(s); } String result = sb.toString();当出现上面的情况时,显然我们要采用第二种方法,因为第一种方法,每次循环都会创建一个String result用于保存结果,除此之外二者基本相同(对于jdk1.5及之后版本)。
(3)为了获得更好的性能,在构造 StirngBuffer 或 StirngBuilder 时应尽可能指定它们的容量。当然,如果你操作的字符串长度(length)不超过 16 个字符就不用了,当不指定容量(capacity)时默认构造一个容量为16的对象。不指定容量会显著降低性能。
(4)StringBuilder一般使用在方法内部来完成类似"+"功能,因为是线程不安全的,所以用完以后可以丢弃。StringBuffer主要用在全局变量中。
(5)相同情况下使用 StirngBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因此:除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用StringBuilder;否则还是用StringBuffer。
java中StringBuffer类的常用方法有有哪些?
StringBuffer sb = new StringBuffer("Hello ");
sb.append("world"); //在sb尾部追加一个字符串, 此时变成 Hello world;
sb.charAt(1) ; //返回下标为1的字符 此处是 e
sb.insert(1,"d"); //在 1 处插入新的字符串 d 此时变为 Hedllo world;
sb.reverse(); //反转字符 此时变成 dlrow olldeH
sb.delete(1,2); //删除字符串 此时变为Hllo world
sb.replace(3,4,"new"); //替换字符串 从 3开始到4结束 此时变为 Hllnewworld
一般用两个 append, toString
StingBuffer类常用的一些方法有:
append( ),表示将括号里的某种数据类型的变量插入某一序列中
charAt( ),返回此序列中指定索引处的 char 值
toString( ),返回此序列中数据的字符串表示形式。
subString( ), 返回一个新的 String,它包含此序列当前所包含的字符子序列。
delete( ),移除此序列的子字符串中的字符。
deletecharAt (), 移除此序列指定位置的 char。
insert( ),表示将括号里的某种数据类型的变量插入某一序列中
reverse( ),将此字符序列用其反转形式取代
setCharAt(int index, char ch ),将给定索引处的字符设置为 ch。
trimToSize (),尝试减少用于字符序列的存储空间。
StringBufferappend(boolean b)
将 boolean 参数的字符串表示形式追加到序列。 StringBufferappend(char c)
将 char 参数的字符串表示形式追加到此序列。 StringBufferappend(char[] str)
将 char 数组参数的字符串表示形式追加到此序列。 StringBufferappend(char[] str, int offset, int len)
将 char 数组参数的子数组的字符串表示形式追加到此序列。 StringBufferappend(CharSequence s)
将指定的 CharSequence 追加到该序列。 StringBufferappend(CharSequence s, int start, int end)
将指定 CharSequence 的子序列追加到此序列。 StringBufferappend(double d)
将 double 参数的字符串表示形式追加到此序列。 StringBufferappend(float f)
将 float 参数的字符串表示形式追加到此序列。 StringBufferappend(int i)
将 int 参数的字符串表示形式追加到此序列。 StringBufferappend(long lng)
将 long 参数的字符串表示形式追加到此序列。 StringBufferappend(Object obj)
追加 Object 参数的字符串表示形式。 StringBufferappend(String str)
将指定的字符串追加到此字符序列。 StringBufferappend(StringBuffer sb)
将指定的 StringBuffer 追加到此序列中。 StringBufferappendCodePoint(int codePoint)
将 codePoint 参数的字符串表示形式追加到此序列。 intcapacity()
返回当前容量。 charcharAt(int index)
返回此序列中指定索引处的 char 值。 intcodePointAt(int index)
返回指定索引处的字符(统一代码点)。 intcodePointBefore(int index)
返回指定索引前的字符(统一代码点)。 intcodePointCount(int beginIndex, int endIndex)
返回此序列指定文本范围内的统一代码点。 StringBufferdelete(int start, int end)
移除此序列的子字符串中的字符。 StringBufferdeleteCharAt(int index)
移除此序列指定位置的 char。 voidensureCapacity(int minimumCapacity)
确保容量至少等于指定的最小值。 voidgetChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将字符从此序列复制到目标字符数组 dst。 intindexOf(String str)
返回第一次出现的指定子字符串在该字符串中的索引。 intindexOf(String str, int fromIndex)
从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。 StringBufferinsert(int offset, boolean b)
将 boolean 参数的字符串表示形式插入此序列中。 StringBufferinsert(int offset, char c)
将 char 参数的字符串表示形式插入此序列中。 StringBufferinsert(int offset, char[] str)
将 char 数组参数的字符串表示形式插入此序列中。 StringBufferinsert(int index, char[] str, int offset, int len)
将数组参数 str 的子数组的字符串表示形式插入此序列中。 StringBufferinsert(int dstOffset, CharSequence s)
将指定 CharSequence 插入此序列中。 StringBufferinsert(int dstOffset, CharSequence s, int start, int end)
将指定 CharSequence 的子序列插入此序列中。 StringBufferinsert(int offset, double d)
将 double 参数的字符串表示形式插入此序列中。 StringBufferinsert(int offset, float f)
将 float 参数的字符串表示形式插入此序列中。 StringBufferinsert(int offset, int i)
将 int 参数的字符串表示形式插入此序列中。 StringBufferinsert(int offset, long l)
将 long 参数的字符串表示形式插入此序列中。 StringBufferinsert(int offset, Object obj)
将 Object 参数的字符串表示形式插入此字符序列中。 StringBufferinsert(int offset, String str)
将字符串插入此字符序列中。 intlastIndexOf(String str)
返回最右边出现的指定子字符串在此字符串中的索引。 intlastIndexOf(String str, int fromIndex)
返回最后一次出现的指定子字符串在此字符串中的索引。 intlength()
返回长度(字符数)。 intoffsetByCodePoints(int index, int codePointOffset)
返回此序列中的一个索引,该索引是从给定 index 偏移 codePointOffset 个代码点后得到的。 StringBufferreplace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。 StringBufferreverse()
将此字符序列用其反转形式取代。 voidsetCharAt(int index, char ch)
将给定索引处的字符设置为 ch。 voidsetLength(int newLength)
设置字符序列的长度。 CharSequencesubSequence(int start, int end)
返回一个新的字符序列,该字符序列是此序列的子序列。 Stringsubstring(int start)
返回一个新的 String,它包含此字符序列当前所包含的字符子序列。 Stringsubstring(int start, int end)
返回一个新的 String,它包含此序列当前所包含的字符子序列。 StringtoString()
返回此序列中数据的字符串表示形式。 voidtrimToSize()
尝试减少用于字符序列的存储空间。
Java中String和StringBuffer的区别
String是普通字符串每次修改String对象的值等同于创建一个新对象,
StringBuffer是缓冲字符串,创建StringBuffer对象会默认有一定容量,
容量被用完之后会自动新增容量
简单点说String相当于数组而StringBuffer则相当于集合
1.就是一个变量和常量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。
2.StringBuffer的内部实现方式和String不同,StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,
3.插入、删除等操作,使用StringBuffer要更加适合一些。String对象创建以后就不能修改了,除非让String类型的引用指向另一个String对象。
String 不是简单类型,而是一个类,它被用来表示字符序列。字符本身符合 Unicode 标准,其初始化方式有两种。
如:String greeting=“Good Morning! \n”;
String greeting=new String(=“Good Morning! \n”);
String的特点是一旦赋值,便不能更改其指向的字符对象,如果更改,则会指向一个新的字符对象 。
StringBuffer是一个具有对象引用传递特点的字符串对象。
StringBuffer对象可以调用其方法动态的进行增加、插入、修改和删除操作,且不用像数组那样事先指定大小,从而实现多次插入字符,一次整体取出的效果,因而操作字符串非常灵活方便。
一旦通过StringBuffer生成最终想要的字符串,就可调用它的toString方法将其转换为一个String对象
String会开辟新的内存,StringBuffer不会。后者一般用于字符串的拼接。每String定义一次就会新建一个字符串对象,StringBuffer只新建一次对象
String与StringBuffer的区别
简单地说,就是一个变量和常量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。
StringBuffer的内部实现方式和String不同,StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。
String:在String类中没有用来改变已有字符串中的某个字符的方法,由于不能改变一个java字符串中的某个单独字符,所以在JDK文档中称String类的对象是不可改变的。然而,不可改变的字符串具有一个很大的优点:编译器可以把字符串设为共享的。
StringBuffer:StringBuffer类属于一种辅助类,可预先分配指定长度的内存块建立一个字符串缓冲区。这样使用StringBuffer类的append方法追加字符 比 String使用 + 操作符添加字符 到 一个已经存在的字符串后面有效率得多。因为使用 + 操作符每一次将字符添加到一个字符串中去时,字符串对象都需要寻找一个新的内存空间来容纳更大的字符串,这无凝是一个非常消耗时间的操作。添加多个字符也就意味着要一次又一次的对字符串重新分配内存。使用StringBuffer类就避免了这个问题。
StringBuffer是线程安全的,在多线程程序中也可以很方便的进行使用,但是程序的执行效率相对来说就要稍微慢一些。
StringBuffer的常用方法
StringBuffer类中的方法要偏重于对字符串的变化例如追加、插入和删除等,这个也是StringBuffer和String类的主要区别。
1、append方法
public StringBuffer append(boolean b)
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer对象的内容也发生改变,例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.append(true);
则对象sb的值将变成”abctrue”。
使用该方法进行字符串的连接,将比String更加节约内容,例如应用于数据库SQL语句的连接,例如:
StringBuffer sb = new StringBuffer();
String user = “test”;
String pwd = “123”;
sb.append(“select * from userInfo where username=“)
.append(user)
.append(“ and pwd=”)
.append(pwd);
这样对象sb的值就是字符串“select * from userInfo where username=test and pwd=123”。
2、deleteCharAt方法
public StringBuffer deleteCharAt(int index)
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“Test”);
sb. deleteCharAt(1);
该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变为”Tst”。
还存在一个功能类似的delete方法:
public StringBuffer delete(int start,int end)
该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb. delete (1,4);
该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。
3、insert方法
public StringBuffer insert(int offset, String s)
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,“false”);
该示例代码的作用是在对象sb的索引值4的位置插入字符串false,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
4、reverse方法
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。
5、setCharAt方法
public void setCharAt(int index, char ch)
该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。
6、trimToSize方法
public void trimToSize()
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费。
7、构造方法:
StringBuffer s0=new StringBuffer();分配了长16字节的字符缓冲区
StringBuffer s1=new StringBuffer(512);分配了512字节的字符缓冲区
8、获取字符串的长度: length()
StringBuffer s = new StringBuffer("www");
int i=s.length();
m.返回字符串的一部分值
substring(int start) //返回从start下标开始以后的字符串
substring(int start,int end) //返回从start到 end-1字符串
9.替换字符串
replace(int start,int end,String str)
s.replace(0,1,"qqq");
10.转换为不变字符串:toString()。
Java中String,StringBuilder和StringBuffer的区别
StringBuilder 速度比较快,但是不是线程安全的~
StringBuffer 相反,降低了速度,但是线程安全
1. 在执行速度方面的比较:StringBuilder > StringBuffer
2. StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。
3. StringBuilder:线程非安全的
StringBuffer:线程安全的
当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。
对于三者使用的总结:1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
JAVA的String类和StringBuffer两个类的区别
最明显区别就是string对象不能操作改变,只能访问。而stringBuffer能够改变数据。
用String添加字符串的时候,不会改变原来的string
用StringBuffer来append,原来的会改变
StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。
所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。
在StringBuffer类中存在很多和String类一样的方法,这些方法在功能上和String类中的功能是完全一样的。
但是有一个最显著的区别在于,对于StringBuffer对象的每次修改都会改变对象自身,这点是和String类最大的区别。
另外由于StringBuffer是线程安全的,所以在多线程程序中也可以很方便的进行使用,但是程序的执行效率相对来说就要稍微慢一些。
1、StringBuffer对象的初始化
StringBuffer对象的初始化不像String类的初始化一样,Java提供的有特殊的语法,而通常情况下一般使用构造方法进行初始化。
例如:
StringBuffer s = new StringBuffer();
这样初始化出的StringBuffer对象是一个空的对象。
如果需要创建带有内容的StringBuffer对象,则可以使用:
StringBuffer s = new StringBuffer(“abc”);
这样初始化出的StringBuffer对象的内容就是字符串”abc”。
需要注意的是,StringBuffer和String属于不同的类型,也不能直接进行强制类型转换,下面的代码都是错误的:
StringBuffer s = “abc”; //赋值类型不匹配StringBuffer s = (StringBuffer)”abc”; //不存在继承关系,无法进行强转
StringBuffer对象和String对象之间的互转的代码如下:
String s = “abc”;StringBuffer sb1 = new StringBuffer(“123”);StringBuffer sb2 = new StringBuffer(s); //String转换为StringBufferString s1 = sb1.toString(); //StringBuffer转换为String
2、StringBuffer的常用方法
StringBuffer类中的方法主要偏重于对于字符串的变化,例如追加、插入和删除等,这个也是StringBuffer和String类的主要区别。
a、append方法
public StringBuffer append(boolean b)
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer对象的内容也发生改变,例如:
StringBuffe sb = new StringBuffer(“abc”);sb.append(true);
则对象sb的值将变成”abctrue”。
使用该方法进行字符串的连接,将比String更加节约内容,例如应用于数据库SQL语句的连接,例如:
StringBuffer sb = new StringBuffer();String user = “test”;String pwd = “123”;sb.append(“select * from userInfo where username=“) .append(user) .append(“ and pwd=”) .append(pwd);
这样对象sb的值就是字符串
“select * from userInfo where username=test and pwd=123”。
b、deleteCharAt方法
public StringBuffer deleteCharAt(int index)
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“Test”);sb.deleteCharAt(1);
该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变为”Tst”。
还存在一个功能类似的delete方法:
public StringBuffer delete(int start,int end)
该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer(“TestString”);sb.delete (1,4);该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。
c、insert方法
public StringBuffer insert(int offset, boolean b)
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);sb.insert(4,false);
该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
d、reverse方法
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。
e、setCharAt方法
public void setCharAt(int index, char ch)
该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);sb.setCharAt(1,’D’);则对象sb的值将变成”aDc”。
f、trimToSize方法
public void trimToSize()
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费。
总之,在实际使用时,String和StringBuffer各有优势和不足,可以根据具体的使用环境,选择对应的类型进行使用。
Java中String,StringBuffer和StringBuilder的区别和堆栈内存分配
1、 String、StringBuffer、StringBuilder都是被final修饰的,是不能够被继承改写的。
2、 String在实例化之后,其内存空间的内容大小是不能够被修改的;而StringBuffer是一个线程安全的可变字符序列,在实例化之后可以动态的修改堆内存中的内容,所以内存长度和大小是可变的;StringBuilder实例化之后内存大小长度也是可变的,不同之处在于StringBuilder不是线程同步,因此操作起来必然比StringBuffer更加高效。
1.三者在执行速度方面的比较:StringBuilder > StringBuffer > String
2.String <(StringBuffer,StringBuilder)的原因
String:字符串常量
StringBuffer:字符创变量
StringBuilder:字符创变量
从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:
String s = "abcd";s = s+1;System.out.print(s);// result : abcd1我们明明就是改变了String型的变量s的,为什么说是没有改变呢? 其实这是一种欺骗,JVM是这样解析这段代码的:首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来 执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多底。
而StringBuffer与StringBuilder就不一样了,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。
3.一个特殊的例子:
String str = “This is only a” + “ simple” + “ test”;StringBuffer builder = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);你会很惊讶的发现,生成str对象的速度简直太快了,而这个时候StringBuffer居然速度上根本一点都不占优势。其实这是JVM的一个把戏,实际上:
String str = “This is only a” + “ simple” + “test”;
其实就是:
String str = “This is only a simple test”;
所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:
String str2 = “This is only a”;
String str3 = “ simple”;
String str4 = “ test”;
String str1 = str2 +str3 + str4;
这时候JVM会规规矩矩的按照原来的方式去做。
4.StringBuilder与 StringBuffer
StringBuilder:线程非安全的
StringBuffer:线程安全的
当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。
对于三者使用的总结: 1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer