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

        

    1. package com.openlab.day15;
    2. import org.junit.jupiter.api.Test;
    3. public class TestString {
    4. @Test
    5. void test01() {
    6. String s = "hello";
    7. String ss = "hello";
    8. System.out.println(s == ss);
    9. }
    10. @Test
    11. void test02() {
    12. String s = "hello";
    13. String ss = new String("hello");
    14. System.out.println(s == ss);
    15. }
    16. @Test
    17. void test03() {
    18. String s = "hello";
    19. String ss = "world";
    20. String sss = "helloworld";
    21. System.out.println(s + ss);
    22. System.out.println(s + ss == sss);
    23. }
    24. @Test
    25. void test04() {
    26. String s = "hello";
    27. String ss = "world";
    28. final String sss = "helloworld";
    29. System.out.println(s + ss == sss);
    30. }
    31. }

     

    1. package com.openlab.demo;
    2. import org.junit.jupiter.api.Test;
    3. class Test01 {
    4. @Test
    5. void test01() {
    6. String s1 = "hello";
    7. final String s2 = "hello";
    8. String ss = new String("hello");
    9. String s3 = "hello2";
    10. String s4 = s1 + 2;
    11. String s5 = s2 + 2;
    12. System.out.println(s1 == s2);
    13. System.out.println(s1 == ss);
    14. System.out.println(s2 == ss);
    15. System.out.println(s3 == s4);
    16. System.out.println(s3 == s5);
    17. }
    18. }

     

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

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

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

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

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

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


    二、StringBuffer和StringBuilder

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

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

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

            System.out.println(i);

    }

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

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

    1. @Test
    2. void testStringBuffer() {
    3. StringBuffer buffer = new StringBuffer();//不写也是空空
    4. //或者StringBuffer buffer = new StringBuffer("");
    5. for(int i = 1; i <= 100; i++) {
    6. buffer.append(i);//在尾部添加
    7. //buffer.insert(0, i);//也可以向其他位置添加
    8. }
    9. System.out.println(buffer.toString());
    10. System.out.println(buffer);
    11. }
    12. @Test
    13. void testStringBuilder() {
    14. StringBuilder builder = new StringBuilder();//不写也是空空
    15. //或者StringBuffer buffer = new StringBuffer("");
    16. for(int i = 1; i <= 100; i++) {
    17. builder.append(i);
    18. }
    19. System.out.println(builder.toString());
    20. System.out.println(builder);
    21. }

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

     (太长,一张显示不下)

    3. StringBuffer和StringBuilder 区别:

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

                    synchronized:同步

                    如:append()方法


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

     

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

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

  • 相关阅读:
    mybatis判断是否为null和空字符串
    责任链模式 行为型设计模式之十
    SfM——八点法计算F矩阵(基础矩阵)与三角测量
    spring---第七篇
    推动智行生态融合!Flyme 迎来大动作,魅族与星纪时代布局初显
    Python基础(六)
    运动式蓝牙耳机哪个牌子好?运动式蓝牙耳机品牌推荐
    Linux常用命令笔记
    MyBatis-Plus标准数据层开发
    MongoDB 中的 push 操作(将文档插入到数组中)
  • 原文地址:https://blog.csdn.net/m0_58679504/article/details/126061381