`
michael8335
  • 浏览: 187586 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

StringBuffer-非完全可变字符串

    博客分类:
  • JAVA
阅读更多
这篇文章也是我对StringBuffer的一点看法,若有不妥之处,还请大家指出
估计Java初学者都知道,String是不可变字符串,StringBuffer是可变字符串,之前我也是这样理解的,但是今天下午,发现了一个奇怪的现象,发现StringBuffer并非完全可变,所以我将之称为非完全可变字符串。
先看看下面这段
public static void main(String[] args) {
		String str = new String("Hello");
		str.concat("World");
		System.out.println(str);
		str.substring(0, 3);
		System.out.println(str);
		System.out.println("<=========================>");
		StringBuffer sb = new StringBuffer("Hello");
		sb.substring(0, 3);
		System.out.println(sb);
		sb.append("World");
		System.out.println(sb);
	}

其输出结果如下:
Hello
Hello
<=========================>
Hello
HelloWorld

通过对比String的substring和StringBuffer的substring方法可以看出,他们都没有改变原来字符串的值,String很好理解,由于是不可变字符串,所以原字符串肯定不会变,但是为何StringBuffer也没变呢??它不是号称可变字符串嘛,那就应该和其他方法一样啊(比如代码中的append方法),改变原来字符串的值啊,但是这里完全没变嘛,再看看StringBuffer的substring方法具体实现。
public String substring(int start, int end) {
	if (start < 0)
	    throw new StringIndexOutOfBoundsException(start);
	if (end > count)
	    throw new StringIndexOutOfBoundsException(end);
	if (start > end)
	    throw new StringIndexOutOfBoundsException(end - start);
        return new String(value, start, end - start);
    }

由此可见,其他该方法也是产生一个新的字符串,并不会更改原字符串的值。
那这里本人就觉得很不理解,为什么StringBuffer的这个方法更String的一样呢??难道这是一个Bug??应该不是,如果要是,SUN早就应该改过来了,那这里SUN到底是出于什么目的要将StringBuffer的substring这样实现呢??不理解
2
10
分享到:
评论
15 楼 michael8335 2012-10-17  
mfkvfn 写道
StringBuffer的subString是返回另一个String并不改变原有StringBuffer对象。
而append方法是操作原对象的。

        StringBuffer sb = new StringBuffer("Hello"); 
        sb.substring(0, 3); 
        System.out.println(sb); 
        sb.append("World"); 
        System.out.println(sb); 

就相当于
int a=1;
a+3;
System.out.println(a);
a+=3;
System.out.println(a);

所有的方法的两种,一种是是带有返回值的方法,称为get方法。另一个是无返回值的方法,称为set方法。
可以看到subString的目的就是得到返回值。它是get方法。而append无返回值它是set方法。
get方法的用法是x=object.method(params)而set方法的用法是object.method(params)

你使用了一个get方法subString而不接受它的返回值。这个在讲法上没有错误,但是在逻辑上是不正确的。应该是String x=sb.substring(0, 3); 结果是sb不会发生变化,而x是取出sb前3个字符后组成的新的String对象。

首先,非常感谢你的解释,和其他骂声和鄙视相比,你详细的解释更显得难能可贵。其实我今天在公司已经看到你的评论了,一直想回复一下,无奈实在太忙,一直到下班回家才能回复你,实在不好意思。
在昨晚发帖的时候,我就估计到会有很多人鄙视我,看来我确实没预期错,但是我还是要把这篇博文发出来,我不能因为怕被鄙视而不敢提出疑问!其实我的疑问算一个牛角尖,我就是想知道,当初设计者为什么要让substring返回一个新的字符串,而不直接在原字符串上面改变,或者说当时设计者为什么不实现一个返回部分字符串的方法(当然通过delete方法也可以到达此目的),我想知道当初设计者是出于什么目的,在一个几乎提供全更改字符串本身的方法类中,留下了三个产生新对象的方法(subSequence(int start, int end) ,substring(int start) ,substring(int start, int end) ),那如果有一天,需要我们自己设计一个类似StringBuffer类的时候,我会不会设计这样三个方法呢??那我到底应该是讲这三个方法产生新对象呢还是在原来对象上做变更呢??这才是我想知道的,我看了很多评论,除了鄙视,大多也只说了表象。或许在大多人看来,这根本就不是一个问题,就像1+1=2一样,很明显1+1=2,但是又有几个能证明1+1=2呢??同时也要感谢那些鄙视我骂我的人,由于你们得存在,给予我更多的学习的动力,在Java方面,我始终把自己放在一个初学者和什么都不知道的地位,这样才能让自己不断的学习和进步,如果有一天我觉得我什么都会了,那也就是我作为软件工程师的最后一天。或许很多人看了我这个评论之后,又会各种鄙视和谩骂,这都是我个人看法和想法,别无它意,并不是每个人都能成为志同道合者。在此希望你能够成为一个优秀的软件工程师,而并非一名普通的coder或者程序员。
14 楼 laogao3232 2012-10-17  
楼主被骂死了,哈哈,完全理解错误。
13 楼 learningBird 2012-10-17  
contact:
If the length of the argument string is 0, then this String object is returned. Otherwise, a new String object is created, representing a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.

substring:
Returns a new String that contains a subsequence of characters currently contained in this sequence. The substring begins at the specified start and extends to the character at index end - 1.

12 楼 onlylau 2012-10-17  
substring的字面意思就是在原字符串里取部分为新字符串,这个操作并不改变原字符串值

这个方法是有返回值的,是产生新字符串

如果你是想通过StringBuilder是截断字符串,那就用delete(start, end)方法
11 楼 mfkvfn 2012-10-17  
看楼主你也写了40多篇文章,涉及到Java、数据库、JSP、Hibernate、Spring、Struts、Linux、设计模式等。应该是一个有几年经验的JAVA老手了,怎么好想不明白呢?
10 楼 mfkvfn 2012-10-17  
StringBuffer的subString是返回另一个String并不改变原有StringBuffer对象。
而append方法是操作原对象的。

        StringBuffer sb = new StringBuffer("Hello"); 
        sb.substring(0, 3); 
        System.out.println(sb); 
        sb.append("World"); 
        System.out.println(sb); 

就相当于
int a=1;
a+3;
System.out.println(a);
a+=3;
System.out.println(a);

所有的方法的两种,一种是是带有返回值的方法,称为get方法。另一个是无返回值的方法,称为set方法。
可以看到subString的目的就是得到返回值。它是get方法。而append无返回值它是set方法。
get方法的用法是x=object.method(params)而set方法的用法是object.method(params)

你使用了一个get方法subString而不接受它的返回值。这个在讲法上没有错误,但是在逻辑上是不正确的。应该是String x=sb.substring(0, 3); 结果是sb不会发生变化,而x是取出sb前3个字符后组成的新的String对象。
9 楼 shenliuyang 2012-10-17  
我不想抨击你,   不知道为啥这也能上首页。
8 楼 TheMatrix 2012-10-17  
记得StringBuilder吗?如果我们要频繁操作字符串,我们建议用StringBuilder,因为它不会重复创建字符串,StringBuffer应该有类似的机制。(方法append)
至于substring,它对于string还是stringbuffer/stringbuilder都是产生一个新的对象的。
7 楼 jeschou 2012-10-17  
片面而且肤浅的观点.

我觉得,你有可能连StringBuffer的文档都没读过.

再者,StringBuffer,StringBuilder 之所以称为可变字符串,是说他 相对于String而言,可能一直接修改他的任何一部分,而不会像String一样,一改就会产生一个新的对象出来.

可变,只是说他有可变的能力,而绝对不是每一个方法都会去改变他
6 楼 wen_jp2002 2012-10-17  
建议详细了解下区别
5 楼 sblig 2012-10-17  
michael8335 写道
ansjsun 写道
..append是操作对象本身

我知道append是操作对象本人,我现在的疑问是为什么substring不去操作对象本身,而去产生一个新的String

substring  讲的是一个返回内容

public String substring(int beginIndex,
                        int endIndex)返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符。因此,该子字符串的长度为 endIndex-beginIndex。
示例:

"hamburger".substring(4, returns "urge"
"smiles".substring(1, 5) returns "mile"

参数:
beginIndex - 起始索引(包括)。
endIndex - 结束索引(不包括)。
4 楼 michael8335 2012-10-16  
ansjsun 写道
..append是操作对象本身

我知道append是操作对象本人,我现在的疑问是为什么substring不去操作对象本身,而去产生一个新的String
3 楼 ansjsun 2012-10-16  
..append是操作对象本身
2 楼 michael8335 2012-10-16  
ansjsun 写道
....我觉得就应该是这个样子的..sbstring 是一个返回值并不是操作对象本身..
string 和 Stringbuffer 内部是char[] 可以这么认为..数组一旦定义不可改变...

一个返回值并不是操作对象本身..
不太理解,这个方法不就是在操作StringBuffer本身嘛,那你说其append方法是操作对象还是返回值呢???
1 楼 ansjsun 2012-10-16  
....我觉得就应该是这个样子的..sbstring 是一个返回值并不是操作对象本身..
string 和 Stringbuffer 内部是char[] 可以这么认为..数组一旦定义不可改变...

相关推荐

    String-StringBuffer-StringBuilder

    首先,`String`是最基本的字符串类,它代表的是不可变的字符序列。一旦创建了一个`String`对象,其内容就不能改变。这是因为`String`对象存储在常量池中,每次对`String`对象的操作都会创建一个新的`String`对象,而...

    JAVA精华 String类一旦初始化就不可以改变,而stringbuffer则可以。它用于封装内容可变的字符串。

    【JAVA精华】在Java编程语言中,String类和StringBuffer类是处理字符串的重要工具,但它们之间存在显著的差异。 1. **String类**:一旦String对象被创建,它的内容就不能更改。这是因为String对象在Java中是不可变...

    java课件-6-字符串和数组.pptx

    而StringBuffer类提供了可变的字符串操作,可以对字符串进行修改。例如,使用StringBuffer类可以将多个字符串连接起来,或者在字符串中插入新的字符。 下面是一个使用StringBuffer类连接多个字符串的示例代码: ``...

    字符串重新排序

    因此,我们在生成新字符串时,可能需要使用StringBuilder或StringBuffer类,它们提供了动态构建字符串的能力,这对于大量操作字符串时的性能至关重要。 总的来说,解决这个问题需要对字符串操作、排序算法、条件...

    java 字符串 正则表达式 详细实例代码

    - Java中的字符串是不可变的,这意味着一旦创建了字符串对象,就不能更改其内容。这由`final`关键字确保,提高了线程安全性。 - 创建字符串的方式有两种:通过字面量(如`String str = "Hello"`)或通过构造函数...

    java三种字符串处理差别

    根据不同的应用场景和需求,Java提供了多种处理字符串的方式,其中最为常见且重要的三种方式分别为:`String`(字符串常量)、`StringBuffer`(线程安全的字符串变量)以及`StringBuilder`(非线程安全的字符串变量...

    java 创建字符串类

    以上就是关于"Java创建字符串类"这一主题的详细阐述,包括`String`类的基本使用、可变字符串类`StringBuilder`和`StringBuffer`,以及相关的操作方法。理解并熟练运用这些知识点对于编写高效且功能丰富的Java程序至...

    Java字符串长度不够前面或后面补0.txt

    1. **String类**:Java中的`String`类用于表示不可变的字符序列。一旦创建了一个`String`对象,其值就不能被更改。 2. **StringBuffer/StringBuilder类**:`StringBuffer`和`StringBuilder`类都用于表示可修改的字符...

    JAVA 字符串 操作

    在Java中,字符串是不可变的。一旦创建,就不能改变其内容。所有看起来改变字符串的方法(如`append()`)都会返回一个新的字符串对象。 3. 字符串比较: - `equals()`方法:用于比较字符串内容是否相同,不区分大...

    字符串查找与替换程序 文件

    StringBuffer类是Java语言中一个可变的字符串处理类,该类提供了许多有用的字符串处理函数,例如 append()、insert()、replace()等。这些函数可以用于字符串的连接、插入和替换等。 StringBuilder类 StringBuilder...

    java实验-字符串.docx

    而StringBuffer类是可变的,可以使用`append()`方法添加内容,而不必每次都创建新对象,因此在处理大量字符串拼接时,StringBuffer的效率更高。 总结来说,这个实验旨在帮助我们理解和掌握Java中字符串的基本操作,...

    Java中字符串.pdf

    - `StringBuffer`类则设计用于处理可变字符串,如果需要频繁地修改字符串内容,使用`StringBuffer`会更高效,因为它允许在原对象上进行修改,避免了创建新的对象。 2. **字符串声明与初始化**: - 声明字符串常量...

    字符串解析

    - 这两个类提供了字符串可变的能力,它们主要用于在需要频繁修改字符串内容的情况下,以提高性能。因为它们内部维护了一个字符数组,可以修改数组的内容,而无需每次都创建新的对象。 - 当涉及到多线程环境时,...

    java字符串实验题目

    这时,StringBuilder和StringBuffer类就派上用场了,它们提供了可变的字符串操作,适合在循环中进行字符串拼接,性能优于使用"+"运算符。 Java异常处理也是编程中的重要组成部分。在处理字符串相关的问题时,可能会...

    StringBuffer总结

    在Java编程语言中,`StringBuffer`是一个非常重要的类,它提供了一种高效的方式来处理可变字符串数据。与不可变的`String`类不同,`StringBuffer`对象可以在创建后进行修改,这使得它非常适合在需要频繁修改字符串...

    截取特定部分字符串

    因为Java中的字符串是不可变的,所以每次修改都会创建新的对象,可能导致内存消耗增加。在这种情况下,使用`StringBuilder`或`StringBuffer`可以提高效率。 7. **异常处理**:在实际应用中,我们需要考虑到可能的...

    将输入的字符串反转 java

    首先,我们要理解Java中的字符串是不可变对象,这意味着一旦创建了字符串对象,就不能更改它的值。因此,反转字符串通常涉及创建一个新的字符串,该字符串包含原始字符串的反向字符顺序。有多种方法可以实现这个目标...

    String ,StringBuffer与StringBuilder

    String, StringBuffer 与 StringBuilder 的区别 ...String 是不可变类,StringBuffer 是可变类,而 StringBuilder 是线程不安全的可变类。根据不同的使用场景,我们可以选择合适的类来实现字符操作。

    java中的字符串处理

    2. **内部实现**:由于字符串不可变,因此Java使用了高效的内部存储结构(如字符数组)来存储字符串的内容,同时提供了多种构造方法以满足不同的使用场景。 #### 三、String类的构造方法 `String`类提供了多种构造...

    Java 字符串与文本相关实例源码

    字符串是不可变的,这意味着一旦创建,就不能更改其内容。本实例源码集主要关注Java中的字符串和文本处理,提供了多种实际应用的示例,帮助开发者深入理解和运用相关功能。 1. **字符串创建与初始化** - `String`...

Global site tag (gtag.js) - Google Analytics