JAVA常用类之——String和String Builler

JAVA常用类之——String和String Builler

     String,String Builder和String Buffer的故事!

    String类是不可变类,通常,String s = "abcd";这样定义的字符串常量存在于内存中的常量池中,而String Buffer类的实例是一个可变的字符串,可以任意的拼接,它有一个toString方法用来转换为String对像。
    String Buffer是线程安全的,但同时也是性能稍低下的,所以又有了String Builder类,它线程不安全,但性能略高。

    一. String类的方法规类
    1. 构造方法
    2. 字符串的获取:indexOf系列是找出字符(串)在该字符串第一次出现的位置,lastIndexOf()是找出最后一次,substring()取字串等。
    3. 字符串的判断:startWith,endsWith判断字符串是否以特定的字符串开头或接尾。
    4. 字符串的转换:toCharArray(),toUpperCase(),toLowerCase()这三个不说了,valueOf是一个方法集,不仅可以将基本类型转换为字符串,还可以将一个引用类型的变量转换为字符串(本质上是调用引用对像的toString方法)。    

    getByte()方法是转成字节数组,这个在TCP/IP通信中是必要的,因为网络上流传的是字节流。
    equals()是对字符串进行比较,它返回的是boolean类型。
    compareTo也是比较,然而它返回的是int类,当字符串不相等时,它返回的是两个字符串第一个不相等的字符差,所以它有可能返-23这样的值。
    concat(),看到它,我想起了C中的strcat这个函数。
    copyValueOf(char[] ...)这个还是一个字符串的获取方法。
    replace,replaceFirst,replaceAll方法是用于替换的。
    trim是去掉字符串两端的空格。
    split方法也是处理字符串常用的方法。
    
    关于String的几个注意点:
    1. 求小串在大串中出现的字数     
public static void main(String[] args)
	{	
		String s1 = "abcabcabcabc";
		String s2 = "abc";
		System.out.println(s1.hashCode());
		System.out.println(s2.hashCode());
		int count = 0;
		int index = 0;
		while((index=s1.indexOf(s2)) != -1){
			count ++;
			s1 = s1.substring(index+s2.length(), s1.length());
		}
		System.out.println(count);
	}
    2. 关于字符串的内存占用问题
    用双引号引起来的字符串都是常量,在编译的时候,被放到内存中方法区中的常量池中,如果在运行时用+号拼起来的字符串都在内存的堆区中()。字符串常量在放之前先在常量池中查找是否有相同的字符串常量,如果有就直接返回地址,如果没有就先放到常量池,然后再返回地址。
    看下面的题:     
public static void main(String[] args)
	{	
		String s1 = "abc";
		String s2 = "abc";
		String s3 = new String("abc");
		String s4 = new String("abc");

		
		System.out.println(s1==s2);	//true
		System.out.println(s2==s3); //false
		System.out.println(s1==s3); //false
		System.out.println(s3==s4); //false
	}

    需要说明一下,在字符串中,equals方法比交的是两个字符串序列是否相等 ,所以如果你用该方法进行判断,那s1,s2,s3,s4都相等了,所以只能用==运算符,对字符串变量来说,==运算符比较的是两个变量本身的值,即两个变量在内存中的首地址,根据上抽的结果有如下的结论:
    1. 对于双引号引起来的变量,是字符串常 量,放在常量池中,所以,在编译的时候,对于s2会首先到常量池中查找有无字符串“abc”,如果有,编 译器就不再分配内存,所以s2 == s1,都指向常量池中的字符串"abc";如果没有,就重新分配内存。
    2. s3是new出来的对像,new出来的对像肯定在堆内存中,然后,new出来的对像中又有一个字符串,所以仍然会在常量池中查找是否有它,如果没有,先在常量池中创建字符串常量,然后在堆中创建对像本身,所以s3指向的是堆内存中的对像。
    3. s4是新new出来的,因为常量池中已经有在了"abc",所以直接在堆内存中创建对像,s4指向这个对像。
    
    那么问题来了,下面的代码创建了几个对像呢?     
	String s3 = new String("abc");
		String s4 = new String("abc");
    如果仅仅是上面两行代码,总共创建了三个对像,首先,看到了双引号,那么常量池中肯定要创建一个"abc",然后在堆中new出了两个对像。

    记住:字符串常量是编译期 分配的内存,而堆中的内存是运行时分配的。使用字符串直接进行拼接会产生大量的临时对像,给垃圾回收带来工作量。

    二. String Buffer和String Builder
    这两个类都有相同的添加,删除,替换,截取,反转能:
   1. 添加: append,insert
   2. 删除: delete,deleteCharAt
   3. 替换: replace
   4. 截取: substring,getChars,charAt,indexOf,lastIndexOf
   5. 反转:reverse
    
    关于String Builder,JDK文档有如下描述:
    一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值