java编程基础总结——17.再学字符串及StringBuffer和StringBuilder

一、String类:

   1. 字符串类Java的底层实现的类,final修饰安全考虑
       字符串本质是一个常量。(一旦被初始化在内存中只有一份)

       字符串缓冲池:字符串常量池(保证了字符串只有一份)

    2. 面试题:java中字符串常量池在什么地方?

        jdk7之前,字符串常量池在方法区(方法区还有类的信息,小整形缓冲池,静态属性,方                法,引用)
        jdk7之后,字符串常量池被设计到了堆内存中(小整形缓冲池,静态 被挪到了元数据区)

    3. 字符串创建方式:
        String s = "Jack";                         // 这种方式创建字符串(先从常量池找Jack,找到了则返回                         Jack这个单词的引用;若找不到,则在常量池中初始化字符串,再将地址返回给s)
       String ss = new String("Jack");    //会创建一个堆内存

   4. 面试题:下面这段代码会创建几个字符串对象

String s = "ljh"//有可能创建一个,有可能不创建

String ss = new String("ljh")//有可能创建一个,有可能创建两个

5. 字符串拼接问题:
    字符串拼接时,如何判断拼接后的结果是否相等(==)
        |-- 常量始终是常量
        |-- 编译时,如果结果确定,则会相等??

    

package com.openlab.day15;

import org.junit.jupiter.api.Test;

public class TestString {
	
	@Test
	void test01() {
		String s = "hello";
		String ss = "hello";
		System.out.println(s == ss);
	}
	
	@Test
	void test02() {
		String s = "hello";
		String ss = new String("hello");
		System.out.println(s == ss);
	}
	
	@Test
	void test03() {
		String s = "hello";
		String ss = "world";
		String sss = "helloworld";
		System.out.println(s + ss);
		System.out.println(s + ss == sss);
	}
	
	@Test
	void test04() {
		String s = "hello";
		String ss = "world";
		final String sss = "helloworld";
		System.out.println(s + ss == sss);
	}
	
	
}

 

package com.openlab.demo;

import org.junit.jupiter.api.Test;

class Test01 {

	@Test
	void test01() {
		String s1 = "hello";
		final String s2 = "hello";
		String ss = new String("hello");
		String s3 = "hello2";
		
		String s4 = s1 + 2;
		String s5 = s2 + 2;
		
		System.out.println(s1 == s2);
		System.out.println(s1 == ss);
		System.out.println(s2 == ss);
		
		System.out.println(s3 == s4);
		System.out.println(s3 == s5);
	}

}

 

        因为字符串是常量,字符串在大量拼接,容易产生垃圾数据。

       字符串是一种常量,一旦产生一个字符,如果常量池中,不存在这个字符串,则会将这个字           符串保存常量池(这个保存时永久性的、只有系统退出才会被销毁)

        字符串不像其他变量,如int a = 10,当后面不用会自动回收,而字符串是常量,无法被回收 

       因此在开发过程中,一定注意,不要大量拼接字符串,以避免产生大量无用的字符串消耗内存

        java为了解决这个问题,引入了两个字符串操作类:StringBuffer和StringBuilder

void test06() {
		//拼接字符串  123456789101112...99100
		String s = "";//存在常量池
		for(int i = 1; i <= 100; i++) {
			s += i;
			//会产生很多的字符串"1" "12" "123"..."123...99" "123...99100"
			//但我们需要的只是最后一个字符串,但在此过程中产生了很多没有用的字符串
		}
		System.out.println(s);
	}


二、StringBuffer和StringBuilder

   1. java提供给用来操作字符串的两个工具类,和字符串没有关系

        是两个对象,不是常量,可以借助这两个对象对字符串进行拼接,因为在拼接过程中产生的            临时变量没有变量保存就消失了。如下面的for循环

for(int i = 0; i < 100; i++){

        System.out.println(i);

}

//每次都赋给了i变量,最终只有一个变量i,其他99个在循环的过程中都舍弃了,因为不是常量,所以一旦创建不用,就自动回收了,不像字符串,是常量,一旦产生会加载到常量区,出不去,gc都没有用

  这两个对象都是jdk底层提供用来拼接大量字符串从对象,不会产生大量无用常量,替代字符串的大量拼接,提高效率。

@Test
	void testStringBuffer() {
		StringBuffer buffer = new StringBuffer();//不写也是空空
		//或者StringBuffer buffer = new StringBuffer("");
		for(int i = 1; i <= 100; i++) {
			buffer.append(i);//在尾部添加
			//buffer.insert(0, i);//也可以向其他位置添加
		}
		System.out.println(buffer.toString());
		System.out.println(buffer);
	}
	
	@Test
	void testStringBuilder() {
		StringBuilder builder = new StringBuilder();//不写也是空空
		//或者StringBuffer buffer = new StringBuffer("");
		for(int i = 1; i <= 100; i++) {
			builder.append(i);
		}
		System.out.println(builder.toString());
		System.out.println(builder);
	}

2. 两个用法一样,都会输出:

 (太长,一张显示不下)

3. StringBuffer和StringBuilder 区别:

         1).StringBuffer:
                所有操作方法上加上了同步锁,所以是线程安全的

                synchronized:同步

                如:append()方法


         2).StringBuilder:
                没有加同步锁,因此非线程安全的!!! 

 

 一般情况下建议使用StringBuilder,效率更高(不加锁效率高)

但是不加锁在高并发,多线程情况下可能会出现线程安全问题,用StringBuffer(但是在这种情况下很少用字符串,所以还是StringBuilder用的更多一点)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值