`
huntfor
  • 浏览: 195222 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java中String基础应用的简单小结(StringBuilder、StringBuffer与String的区别)

 
阅读更多

一直以为String、Array、Collection、File、I-O是所有编程语言的基础也是重点。

今天简单对String做以简单的小结。

 

《编程思想》中的开场语:可以证明,字符串操作是计算机程序设计中最常见的行为。尤其是在java大展拳脚的Web系统中。

 

Java中String的几个要点:

       1.String是不可变的

       2.String的基本操作

       3.StringBuffer & StringBuilder

进击的String:

       1.格式化的输出

       2.正则表达式

       3.扫描输入

       

1.不可变的String

JDK 写道
The String class represents character strings. Strings are constant. their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.

        根据JDK的描述,我们可以看到String类型在从创建之后就是不可变的,只能shared,不能change.
 

JDK 写道
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString.
简单翻译
java提供了对字符串链接符+,已经任何对象转换成string对象的特殊支持。链接是通过StringBuilder(java SE5引入,之前一直用的StringBuffer,线程安全的,为了提高效率,改用builder)或者StringBuffer类的append方法实现的。对象到String的转换则是通过toString接口实现的。该接口是有Object类定义,被所有类继承。

      《thinking In java》按:String类中任何看来会修改String值的方法,实际都是创建了一个全新的String对象,以包含修改后的字符串内容。而最初的String对象丝毫未动。

//	String abc = "abc";		两种
	char[] data = {'a', 'b', 'c'};
	String abc = new String(data);		
	
        System.out.println(abc.toUpperCase());          //ABC
	System.out.println(abc);                        //abc

 上面可以看到虽然对abc做了upperCase,但是abc本身并没有做出任何变化。实际上abc.toUpperCase只是返回了一个新的String对象。

 

2.String类的基本操作

 

package test;

public class TestString {

	public static void main(String[] args) {
		String test = new String("hello WORLD! ");
		String replace = test.replace('o', 'a');
		 	
		String upperCase = test.toUpperCase();
	    System.out.println(upperCase);//HELLO WORLD! 
	    
	    String lowerCase = test.toLowerCase();//hello world! 
	    System.out.println(lowerCase);
	    
	    char index = test.charAt(3);
	    System.out.println(index);//l
	    
	    int codePoint = test.codePointAt(3);
	    System.out.println(codePoint);//108
	    //compareToIgnoreCase
	    System.out.println(test.compareToIgnoreCase(lowerCase));//0
	    System.out.println(test.compareToIgnoreCase(upperCase));//0
	    System.out.println(upperCase.compareToIgnoreCase(lowerCase));//0
	    //compareTo
	    System.out.println(upperCase.compareTo(lowerCase));//-32
	    //concat
	    System.out.println(lowerCase.concat(upperCase));//hello world! HELLO WORLD! 
	    //substring
	    System.out.println(test.substring(2));//llo WORLD! 
	    System.out.println(test.substring(0, 5));//hello
	    //trim
	    System.out.println(test.trim());//hello WORLD!注意这里的空格被去掉了

	    System.out.println(test);//hello WORLD! 最后一个有空格,test从没改变
	}
	
	
}

 3.StringBuffer & StringBuilder

 

 JDK中给出的StringBuffer的解释:

 

A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified.

String buffers are safe for use by multiple threads.

The principal operations on a StringBuffer are the append and insert methods, which are overloaded so as to accept data of any type. Each effectively converts a given datum to a string and then appends or inserts the characters of that string to the string buffer. 

      简单解释一下:

 

StringBuffers是线程安全的,可变的字符序列。StringBuffer很像String,不过可以修改。
StringBuffer最主要的操作是appendinsert接口,这些接口都已经被重写过以便支持各种数据类型。这些方法首先将给定数据转换成String类型,然后再将该string对象appends 或者insert到stringbuffer对象中。事实上,sb.append(x)的效果与sb.insert(sb.length(),x)是一样的。

 

    简单测试一下:

 

		StringBuffer buffer = new StringBuffer("hello world! ");
		buffer.append("I am me! ");
		System.out.println(buffer);//hello world! I am me! 
		buffer.insert(5, " my");
		System.out.println(buffer);//hello my world! I am me! 

 

 可以看粗,StringBuffer的确是像一个String,但是可以修改。

 

  有意思的是JDK文档中给出的最后一段话

Every string buffer has a capacity. As long as the length of the character sequence contained in the string buffer does not exceed the capacity, it is not necessary to allocate a new internal buffer array. If the internal buffer overflows, it is automatically made larger. As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.

 

 

    上文中提到StringBuffer是有容积的。只要string buffer 中的字符序列不超过buffer的容积,就不会再分配新的array给它,否则溢出的话,会自动扩展。JDK5提供了stringbuffer的一个单线程等价类——StringBuilder。同时JDK建议,应该优先考虑StringBuilder,因为它的接口与StringBuffer完全一样,但是要更快,不过是非线程安全的。

 

 

 再看StringBuilder:

 

    JDK给的定义:

A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

   

    与上面的StringBuffer后面给出的对比如出一辙,可笑的是,后面的关于接口功能的介绍貌似是从StringBuffer文档中直接copy过来的,由此可见,StringBuilder实际上是单线程情况下高效版StringBuffer,功能几乎完全一样。

 

 

来个小结:

       String类不可变,在每次对String对象做改变操作的时候总是会生成新的String对象,如果程序中有频繁的改动字符串内容的操作,那么势必会在内存中产生许多无引用对象,导致GC,拖慢速度。

       在上面StringBuffer的JDK文档中也说的很明白,StringBuffer最主要的操作就是append,insert等改变string内容的接口,因此如果需要频繁的修改String内容的话,推荐使用StringBuffer(多线程)、StringBuilder(单线程)。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics