• Java String、StringBuffer 和 StringBuilder 的区别和理解


    String

    String:字符串常量,字符串长度不可变。Java中String是immutable(不可变)的。

    String声明为final的,不可被继承

    String实现了Serializable接口:表示字符串是支持序列化的实现了Comparable接口:表示String可以比较大小

    String在内部定义了final的char型数组(final char[]),用于存储字符串数据。

    String代表一个不可变的字符序列。具有不变性。

    1. /** The value is used for character storage. */
    2. private final char value[];
    3. /** The offset is the first index of the storage that is used. */
    4. private final int offset;
    5. /** The count is the number of characters in the String. */
    6. private final int count;

    初始化方式:常用的两种:

    1. //通过字面量的方式定义
    2. String s1 = "java";
    3. //通过new + 构造器方式
    4. String s2 = new String("java2");

    会开辟两块堆内存空间,不会自动保存在常量池中,可以使用intern()方法手工入池。

    String的常用用法详解

    1.int length():返回字符串的长度

    1. String s1 ="HelloWorld";
    2. System.out.println(s1.length());//10

     2.char chaeAt():返回索引处(index)的字符

         

    1. String s1 ="HelloWorld";
    2. System.out.println(s1.charAt(5));//W

      3.boolean isEmpty():判断是否是空字符串

    1. String s1 ="HelloWorld";
    2. System.out.println(s1.isEmpty());//false


    4.String toLowerCase():使用默认语言环境,将String中的所有字符转换为小写
     

    1. String s1 ="HelloWorld";
    2. String s2 = s1.toLowerCase();
    3. System.out.println(s2);//helloworld


    5.String toUpperCase():使用默认语言环境,将String中的所有字符转换为大写(toLowerCase() 小写)

    1. String str = "HELLO" ;
    2. System.out.println(str.toLowerCase()); //hello
    3. String str = "hello" ;
    4. System.out.println(str.toUpperCase()); // HELLO


    6.String trim():返回字符串的副本,忽略字符串前和字符串后的空白
     

    1. String s3 = "     he   ll   o   w  or l d      ";
    2. String s4 = s3.trim();
    3. System.out.println("----------" + s4 + "-----------");
    4. //"he   ll   o   w  or l d"


    7.boolean equals():比较两个字符串的内容是否相同
     

    1.  String s6 = "abc";
    2.  String s7 = "cde";
    3.  System.out.println(s6.equals(s7));//false


    8.String concat():将指定字符串连接到此字符串的结尾。
     

    1. String s1 = "abc";
    2. System.out.println(s1.concat("def"))//abcdef


    9.int compareTo():比较两个字符串的大小
     

    1. String s6 = "abc";
    2. String s7 = "cde";
    3. int i = s6.compareTo(s7);
    4. System.out.println(i);//-2


    10.String substring((int beginIndex):返回一个新的字符串,它是此字符串的从 beginIndex开始截取到最后的一个子字符串
     

    1.  String s8 = "你是如此美丽";
    2.  String s9 = s8.substring(2);
    3.  System.out.println(s9);//如此美丽


    11.boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列 时,返回 true

    1. String str1 = "helloworld";
    2. String str2 = "wo";
    3. boolean b4 = str1.contains(str2);//true


    12.int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引

    1. String str1 = "helloworld";
    2. System.out.println(str1.indexOf("lo"));//3
    3. //若不存在,返回-1


    13.int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
     

    1. String str1 = "helloworld";
    2. System.out.println(str1.lastIndexOf("o"));//6


    14.String replace(char oldChar, char newChar):返回一个新的字符串,它是 通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
    15.boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
    16.String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。


     

    StringBuffer 

     接口文档:详情可自行查看

    StringBuffer 的特点

    • StringBuffer 类的对象可被多次修改,且对 StringBuffer 对象本身操作;
    • StringBuffer 类使用 synchronized 同步修饰方法,线程安全。

    StringBuffer 的构造方法

    • StringBuffer():构造一个没有字符的字符串缓冲区,初始容量为16字符;
    • StringBuffer(String str):构造一个初始化为指定内容的字符串缓冲区;
    • StringBuffer(int capacity):构造一个没有字符的字符串缓冲区和指定的初始容量;
       

    实例:

    1. /* 构造方法 */
    2. // 构造一个没有字符的字符串缓冲区,初始容量为16
    3. StringBuffer sb1 = new StringBuffer();
    4. System.out.println(sb1.capacity()); // 16
    5. System.out.println(sb1.length()); // 0
    6. // 构造一个指定字符串的字符串缓冲区,容量 = 16(初始容量) + 字符串长度
    7. StringBuffer sb2 = new StringBuffer("Java");
    8. System.out.println(sb2.capacity()); // 20 = 16 + 4
    9. System.out.println(sb2.length()); // 4
    10. // 构造指定容量的字符串缓冲区
    11. StringBuffer sb3 = new StringBuffer(12);
    12. System.out.println(sb3.capacity()); // 12
    13. System.out.println(sb3.length()); // 0

    StringBuffer 的常用方法

    1. append(): 追加,在字符串末尾添加;
    2. delete():删除,删除指定索引处的字符;
    3. replace():替换,用指定的String中的字符替换子字符串中的String;
    4. reverse():反转;
    5. substring():截取返回一个新的 String,它包含此序列当前所包含的字符子序列
    6. insert():插入,指定位置插入字符串;
       
    1. /* 常用方法 */
    2. StringBuffer str1 = new StringBuffer("I love ");
    3. // append(): 追加
    4. System.out.println("append()前str1: " + str1); // I love
    5. str1.append("Java!");
    6. System.out.println("append()后str1: " + str1); // I love Java!
    7. // delete(): 删除
    8. System.out.println("delete()前str1: " + str1); // I love Java!
    9. str1.delete(3, 5);
    10. System.out.println("delete()后str1: " + str1); // I le Java!
    11. // replace(): 替换
    12. System.out.println("replace()前str1: " + str1); // I le Java!
    13. str1.replace(1, 4, "*******");
    14. System.out.println("replace()后str1: " + str1); // I******* Java!
    15. // reverse(): 反转
    16. System.out.println("reverse()前str1: " + str1); // I******* Java!
    17. str1.reverse();
    18. System.out.println("reverse()后str1: " + str1); // !avaJ *******I
    19. // substring(): 截取
    20. System.out.println("substring()前str1: " + str1); // !avaJ *******I
    21. String str2 = str1.substring(3, 8);
    22. System.out.println("substring()后str1: " + str2); // aJ **
    23. // insert(): 插入
    24. System.out.println("insert()前str1: " + str1); // !avaJ *******I
    25. str1.insert(3, "hahaha");
    26. System.out.println("insert()后str1: " + str1); // !avhahahaaJ *******I

    运行结果:

    1. append()前str1: I love
    2. append()后str1: I love Java!
    3. delete()前str1: I love Java!
    4. delete()后str1: I le Java!
    5. replace()前str1: I le Java!
    6. replace()后str1: I******* Java!
    7. reverse()前str1: I******* Java!
    8. reverse()后str1: !avaJ *******I
    9. substring()前str1: !avaJ *******I
    10. substring()后str1: aJ **
    11. insert()前str1: !avaJ *******I
    12. insert()后str1: !avhahahaaJ *******I

     构造方法

    1. public static void main(String[] args){
    2. /* 构造方法 */
    3. // 构造一个没有字符的字符串缓冲区,初始容量为16
    4. StringBuffer sb1 = new StringBuffer();
    5. System.out.println(sb1.capacity()); // 16
    6. System.out.println(sb1.length()); // 0
    7. // 构造一个指定字符串的字符串缓冲区,容量 = 16(初始容量) + 字符串长度
    8. StringBuffer sb2 = new StringBuffer("Java");
    9. System.out.println(sb2.capacity()); // 20 = 16 + 4
    10. System.out.println(sb2.length()); // 4
    11. // 构造指定容量的字符串缓冲区
    12. StringBuffer sb3 = new StringBuffer(12);
    13. System.out.println(sb3.capacity()); // 12
    14. System.out.println(sb3.length()); // 0
    15. /* 常用方法 */
    16. StringBuffer str1 = new StringBuffer("I love ");
    17. // append(): 追加
    18. System.out.println("append()前str1: " + str1); // I love
    19. str1.append("Java!");
    20. System.out.println("append()后str1: " + str1); // I love Java!
    21. // delete(): 删除
    22. System.out.println("delete()前str1: " + str1); // I love Java!
    23. str1.delete(3, 5);
    24. System.out.println("delete()后str1: " + str1); // I le Java!
    25. // replace(): 替换
    26. System.out.println("replace()前str1: " + str1); // I le Java!
    27. str1.replace(1, 4, "*******");
    28. System.out.println("replace()后str1: " + str1); // I******* Java!
    29. // reverse(): 反转
    30. System.out.println("reverse()前str1: " + str1); // I******* Java!
    31. str1.reverse();
    32. System.out.println("reverse()后str1: " + str1); // !avaJ *******I
    33. // substring(): 截取
    34. System.out.println("substring()前str1: " + str1); // !avaJ *******I
    35. String str2 = str1.substring(3, 8);
    36. System.out.println("substring()后str1: " + str2); // aJ **
    37. // insert(): 插入
    38. System.out.println("insert()前str1: " + str1); // !avaJ *******I
    39. str1.insert(3, "hahaha");
    40. System.out.println("insert()后str1: " + str1); // !avhahahaaJ *******I
    41. }

    运行结果:

    1. 16
    2. 0
    3. 20
    4. 4
    5. 12
    6. 0
    7. append()前str1: I love
    8. append()后str1: I love Java!
    9. delete()前str1: I love Java!
    10. delete()后str1: I le Java!
    11. replace()前str1: I le Java!
    12. replace()后str1: I******* Java!
    13. reverse()前str1: I******* Java!
    14. reverse()后str1: !avaJ *******I
    15. substring()前str1: !avaJ *******I
    16. substring()后str1: aJ **
    17. insert()前str1: !avaJ *******I
    18. insert()后str1: !avhahahaaJ *******I

    StringBuilder 

    接口文档:详情可自行查看

    字符串变量(非线程安全)。在内部,StringBuilder 对象被当作是一个包含字符序列的变长数组。

    java.lang.StringBuilder 是一个可变的字符序列,是 JDK5.0 新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)

    三种重载构造器的使用案例

    1. //几种重载构造器的使用案例
    2. StringBuilder sb1 =new StringBuilder();//#1 无参
    3. StringBuilder sb2=new StringBuilder("123");//#2
    4. StringBuilder sb3=new StringBuilder(123);//#3 有参

    在StringBuilder类重载的三种构造器中都调用了父类abstractStringBuilder重载的构造器,在StringBuilder类重载的三种构造器中传参,实际上都是在指定继承于abstractStringBuilder父类中的char类型数组的长度

    1. 调用StringBuilder类中的空参构造器,在调用abstractStringBuilder父类的构造器时默认传入16,即char类型value数组的长度为16.
    2. 调用StringBuilder类中的形参为string类型的构造器,在调用abstractStringBuilder父类的构造器时传入该string类型字符串的长度string.length()+16,即char类型value数组的长度为string.length()+16.(16为构造器默认长度)
    3. 调用StringBuilder类中的形参为int类型的构造器,在调用abstractStringBuilder父类的构造器时传入该int类型数据,即char类型value数组的长度为该int类型数据值.

    append()方法的使用

    对于string类型的字符串,在实现拼接操作时可以使用“+”连接符、concat()方法、join()方法(join()方法用于多个字符串或字符串数组按照指定字符串逐个拼接)

    这三个方法的使用都不会改变原字符串,而是返回一个新的字符串

    1. String str="x";
    2. str=str+"a";
    3. str=str.concat("b");
    4. System.out.println(str);
    5. String str1="w";
    6. str=str.join("@", str,str1);
    7. System.out.println(str);

    运行结果:

    1. xab
    2. xab@w

    StringBuilder类中append()方法的具体使用:在原字符串尾部直接追加一个字符串或字符,改变原字符串

    1. //append()方法的使用
    2. StringBuilder le =new StringBuilder("好好");
    3. le.append("学习").append("天天向上");
    4. System.out.println(le);
    5. }

    运行结果是:

    好好学习天天向上

     replace()方法的使用

     string类中replace()方法:将指定原字符串中的子字符串或字符替换为指定的字符串或字符。不会改变原字符串,而是返回一个新的字符串

    1. //string类中replace()方法的使用
    2. String str="人生在世,孰能无错";
    3. str=str.replace("人生", "老子").replace('错', '过');
    4. System.out.println(str);

    运行结果:

    老子在世,孰能无过

    StringBuilder类中replace()方法的具体使用:将从指定启使下标开始到指定结尾下标(不含尾下标)的子字符串替换为指定字符串。

    1. replace()方法的使用
    2. StringBuilder le =new StringBuilder("不知所措啊");
    3. le.replace(1, 3, "lel");
    4. System.out.println(le);
    5. }

    运行结果:

    不lel措啊

    delete()方法的使用:将从指定启使下标至指定结尾下标(不含尾下标)的子字符串删除

    1. //delete()方法的使用
    2. StringBuilder le = new StringBuilder("好好学习");
    3. le.delete(1, 3);
    4. System.out.println(le);
    5. }

    运行结果:

    好习

    insert()方法的使用:在指定下标位置插入字符串、字符、布尔值等

    1. //insert()方法的使用
    2. StringBuilder le=new StringBuilder("好好学习");
    3. le.insert(3, "天").insert(4, '弟').insert(0, "好的");
    4. System.out.println(le);
    好的好好学天弟习

    reverse()方法的使用:将原字符串逆序

    1. //reverse()方法的使用
    2. StringBuilder le=new StringBuilder("不服就干别哔哔");
    3. le.reverse();
    4. System.out.println(le);

    运行结果

    哔哔别干就服不

    1. public class RunoobTest{
    2. public static void main(String args[]){
    3. StringBuilder sb = new StringBuilder(10);
    4. sb.append("Runoob..");
    5. System.out.println(sb);
    6. sb.append("!");
    7. System.out.println(sb);
    8. sb.insert(8, "Java");
    9. System.out.println(sb);
    10. sb.delete(5,8);
    11. System.out.println(sb);
    12. }
    13. }

    运行结果:

    1. Runoob..
    2. Runoob..!
    3. Runoob..Java!
    4. RunooJava!

    StringBuffer 和 StringBuilder 类的区别

    StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。

    StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

    由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

    1

    2

    3

    4

    5

    6

    7

    public class Test{   public static void main(String args[]){

        StringBuffer sBuffer = new StringBuffer("菜鸟教程官网:");    

        sBuffer.append("www");    

        sBuffer.append(".runoob");    

        sBuffer.append(".com");    

        System.out.println(sBuffer);     

        }}   

    以上实例编译运行结果如下:

    1

    菜鸟教程官网:www.runoob.com

    String、StringBuffer、StringBuilder的区别

    1. String是不可变的{final修饰},如果尝试去修改,会新⽣成⼀个字符串对象,StringBuffer和StringBuilder是可变的

    2. StringBuffer是线程安全的{synchronized},StringBuilder是线程不安全的,所以在单线程环境下StringBuilder效率会更⾼

    使用建议:

            (1) 如果要操作少量的数据,建议用String;

            (2) 如果在多线程操作字符串缓冲区下操作大量的数据,建议使用SreingBuffer;

            (3) 如果在单线程操作字符串缓冲区下操作大量数据,建议使用StringBuilder。

    练习:

    描述

    将一个由英文字母组成的字符串转换成从末尾开始每三个字母用逗号分隔的形式。

    输入描述:

    一个字符串

    输出描述:

    修改后的字符串

    理解解释:

    因为String类型字符串不可变,我们用这个字符串创建一个新的StringBuilder型的字符串,然后从字符串末尾第3位开始,每次三位三位地遍历,将逗号用insert函数插入其中。最后将StringBuilder型转变成String输出即可。

    1. public static void main(String[] args) {
    2. Scanner scanner = new Scanner(System.in);
    3. String str = scanner.next();
    4. //write your code here......
    5. StringBuilder m = new StringBuilder();
    6. //用str初始化m
    7. m.append(str);
    8. //遍历m,每次跳跃3个字符,然后插入一个','
    9. for(int i=str.length()-3;i>=0;i-=3)
    10. {
    11. //利用for循环在每3个后加入逗号
    12. m.insert(i,",");
    13. }
    14. //输出改变后的字符串
    15. System.out.println(m.toString());
    16. }

    运行结果:

    1. aaabbbcccd
    2. a,aab,bbc,ccd

    引用文章:1,2,3

  • 相关阅读:
    制造企业如何做好MES管理系统需求分析
    leetcode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
    Windows/Ubuntu安装frida和objection
    计算机毕业设计ssm人力资源管理系统3118c系统+程序+源码+lw+远程部署
    雪糕冰淇淋经营配送小程序商城效果如何
    鲸探发布点评:9月8日发售《汝阳黄河巨龙》数字藏品
    leetcode:762. 二进制表示中质数个计算置位(python3解法)
    组队竞赛(int溢出问题)
    Ubuntu-虚拟机常见问题
    Python-Python高阶技巧:HTTP协议、静态Web服务器程序开发、循环接收客户端的连接请求
  • 原文地址:https://blog.csdn.net/qq_42055933/article/details/126028546