StringBuffer 和 StringBuilder

StringBuffer 和 StringBuilder

字符串

1.什么是字符串?

  • 字符串基本概念
      1. 字符串是0个或多个字符的有序集合
      1. 在Java中,字符串 String 是一个类,它封装了字符串数据和诸多操作方法;所有的方法都不能修改字符串本身,因此,Java中的字符串是一个常量
      1. 本质上,String 类中使用一个char[]来存储字符串
        注:我们学习字符串,其实就是学习字符串的操作方法

2.字符串的使用

2.1 创建字符串

语法

    String s1="abc";    //语法一
    String s2=new String("cde");    //语法二

两种语法的区别(内存结构图)
语法一内存结构图
在这里插入图片描述

语法二
在这里插入图片描述

注:在语法二的代码中实际上创建了2个对象(面试题)

2.2 字符串方法
1. 获取字符串长度
    String s="abc";
    System.out.println(s.length());
2. 字符串比较
    String s1=new String("abc");
    String s2=new String("abc");
    System.out.println(s1==s2);     //false
    System.out.println(s1.equals(s2));//true

注:
1. 双等符号比较的是内存地址
2. equals()方法比较的是字符串的内容

面试题1:如下代码的结果是什么?

    String s1="abc";
    String s2="abc";
    System.out.println(s1==s2);//true

以上代码的内存结构图
在这里插入图片描述

面试题2:如下代码的结果是什么?

String s1 = new String("abc");
String s2 = "abc";
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true

以上代码的内存结构图
在这里插入图片描述

3. 字符串比较的其他方法
String s1 = "abc";
String s2 = "ABC";
System.out.println(s1.equals(s2)); // false
System.out.println(s1.equalsIgnoreCase(s2)); // true
System.out.println(s1.toLowerCase.equals(s2.toLowerCase())); // true
System.out.println(s1.toUpperCase.equals(s2.toUpperCase())); // true

1. boolean s1.equalsIgnoreCase(String s2) 忽略大小写比较字符串
2. String s1.toUpperCase() 将字符串转换为大写
3. String s1.toLowerCase() 将字符串转换为小写
4. 字符串连接
int java = 100;
int c = 98;
System.out.println("java : " + java);
System.out.println("c : ".concat(c + ""));
1. 使用 + 拼接字符串
2. String s1.concat(String s2) 拼接字符串
3. 拼接字符串的结果是生成一个新的拼接后的字符串,原字符串不变。
5. 字符串查找
String s1 = "This is a bus.";
int p1 = s1.indexOf("is"); // p1 : 2
int p2 = s1.lastIndexOf("is"); // p2 : 5
int p3 = s1.indexOf("ab"); // p3 : -1
1. int s1.indexOf(String s2) 在主串 s1 中查找子串 s2 的位置,如果找不到,
返回 -1;
2. int s1.indexOf(char c) 在主串 s1 中查找字符 c 的位置,如果找不到,返回
-1;
3. int s1.lastIndexOf(String s2) 在主串 s1 中查找子串 s2 的位置,如果找不
到,返回 -1;
4. int s1.lastIndexOf(char c) 在主串 s1 中反向查找字符 c 的位置,如果找不
到,返回 -1;

6. 字符串截取
String s1 = "abcdefg ";
String s2 = s1.substring(3, 5); // s2 : de
String s3 = s1.substring(3); // s3 : defg
String s4 = s1.trim(); // s4 : abcdefg
1. String s1.substring(int pos1, int pos2) 在主串 s1 中截取子串,子串范围
从主串的 pos1 位置开始到 pos2 - 1 为止;
2. String s1.substring(int pos) 在主串 s1 中截取子串,子串范围从主串的
pos1 位置开始到主串结束位置;
3. String s1.trim() 将 s1 首尾的空格去除。

7. 字符串拆分
String s1 = "086-0379-3995995";
String[] a = s1.split("-"); // a : {"086", "0379", "3995995"}

String[] s1.split(String s2) 将主串 s1 按照子串 s2 劈开,结果是分解成若干个子串,
返回这些子串的数组;

String不为人知的秘密

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

        //String 是被 final 修饰的 每次更改都会重新开辟一个新的内存地址
        String s1=new String("a");
        String s2=new String("a");
        //==比较的是内存地址
        //equals在string里面比较的是值
        System.out.println(s1==s2);//false
        System.out.println(s1.equals(s2));//true

        String s3="b";//指向同一个内存地址
        String s4="b";
        System.out.println(s3==s4);//true
        System.out.println(s3.equals(s4));//true
    }
}

StringStringBuffer 在 Java 中都用于处理字符串,但它们之间存在一些重要的区别。

  1. 不可变性
    String 是不可变的。这意味着一旦创建了一个 String 对象,就不能更改它。每次对 String 进行修改,都会创建一个新的 String 对象。这可能会导致内存和性能问题,特别是在处理大量字符串操作时。
String s = "Hello";
s = s + " World"; // s now refers to a new String object

另一方面,StringBuffer 是可变的。这意味着可以修改 StringBuffer 对象本身,而不会创建新的对象。

StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // The original StringBuffer is modified
  1. 性能
    由于 String 的不可变性,对于需要大量修改字符串的操作,使用 StringBuffer 通常会更快。在处理大量字符串连接或修改操作时,使用 String 可能会导致大量的对象创建和垃圾收集。
  2. 线程安全
    StringBuffer 是线程安全的,因为它的大多数方法都是同步的。这意味着多个线程可以同时操作同一个 StringBuffer 对象,而不会导致数据不一致。

相比之下,String 的不可变性使其线程安全,因为没有方法可以修改 String 对象。但是,对于可变字符串操作(如字符串连接),可能需要额外的同步措施来确保线程安全。
4. 用途
String 更适合于表示不可变的数据或常量,例如文件路径或消息字符串。

另一方面,StringBuffer 更适合于需要修改的字符串,例如在拼接或修改字符串时。
5. 内存占用
由于 StringBuffer 的可变性,它通常会占用更多的内存。因此,在内存敏感的应用程序中,应优先考虑使用 String
6. 方法
StringBuffer 提供了一组更丰富的方法来修改字符串,例如 append(), insert(), delete(), replace() 等。相比之下,String 只提供了一些基本的字符串操作方法。

StringBuffer 和 StringBuilder的区别

StringBufferStringBuilder都用于处理可变字符串,但它们之间存在一些重要的区别。

  1. 线程安全
    StringBuffer 是线程安全的,因为它的所有方法都是同步的。这意味着多个线程可以同时操作同一个 StringBuffer 对象,而不会导致数据不一致。

相比之下,StringBuilder 不是线程安全的。它的方法没有同步机制,因此在多线程环境下可能会引发问题。然而,由于其非线程安全的特性,StringBuilder 在单线程环境下的性能通常会优于 StringBuffer
2. 性能
在性能方面,StringBuilder 通常要优于 StringBuffer,尤其是在没有多线程冲突的情况下。这是因为 StringBuilder 的方法没有进行同步处理,所以执行起来会更快。
3. 用途
如果你在单线程环境下工作,或者需要更高的性能,那么 StringBuilder 是一个更好的选择。如果你在多线程环境下工作,且需要确保线程安全,那么 StringBuffer 是更适合的选择。

总的来说,选择 StringBuffer 还是 StringBuilder,主要取决于你的应用场景和需求。

StringBuffer

        StringBuffer stringBuffer=new StringBuffer("ABC");
        StringBuffer  stringBuffer1=stringBuffer.append("DEF");

        System.out.println(stringBuffer==stringBuffer1);

StringBuffer 的优点

由于 String 对象是常量(实际上是使用了不变模式),所以在进行频繁的字符串拼接、插入、
删除操作时,会产生大量的内存垃圾;此时,因选择 StringBuffer 或者 StringBuilder类。

StringBuffer 的使用

StringBuffer 拥有几乎 String 的所有方法,只是实现方式有所不同;StringBuffer 还拥有 String所没有的方法。

1. 追加字符串
StringBuffer sb = new StringBuffer("学 IT"); // sb : 学 IT
StringBuffer sb1 = sb.append("好工作"); // sb, sb1 : 学 IT好工作
StringBuffer sb2 = sb.append("高端大气上档次"); // sb, sb1, sb2 : 学 IT好工作高端大气上档次
String s1.append(String s2) 在字符串 s1 后追加字符串 s2,并返回 s1;

以上代码的内存结构图
在这里插入图片描述

2. 插入字符串
StringBuffer sb1 = new StringBuffer("abc");
sb1.insert(1, "123"); // sb1 : "a123bc"
String s1.insert(int pos, String s2) 在字符串 s1 的 pos 位置插入字符串 s2,并返回s1。

StringBuilder

3.1 StringBuilder概述

StringBuilder 是一个可变的字符串类,我们可以把它看成是一个容器
这里的可变指的是StringBuilder对象中的内容是可变的

String 和 StringBuilder的区别:

  • String:内容是不可变的
  • StringBuilder:内容是可变的

3.2 StringBuilder 构造方法

方法名说明
public StringBuilder()创建一个空白可变字符串对象,不含有任何内容
public StringBuilder(String str)根据字符串的内容,来创建可变字符串对象

public class StringDemo01 {
    public static void main(String[] args) {
        //public String():创建一个空白字符串对象,不含有任何内容
        String s1=new String();
        System.out.println("s1"+s1);

        //public String(char[] chs):根据字符数组内容 来创建字符串对象
        char[] chs={'a','b','c'};
        String s2=new String(chs);
        System.out.println("s2:"+s2);

        //public String(byte[] bys):根据字节数组内容,来创建字符串对象
        byte[] bys={97,98,99,100};
        String s3=new String(bys);
        System.out.println("s3:"+s3);

        //String s="abc"; 直接赋值的方法创建字符串对象,内容就是abc
        String s4="abc";
        System.out.println("s4:"+s4);
        //获取字符串长度
        System.out.println(s4.length());
        //遍历字符串
        for (int i = 0; i < s4.length(); i++) {
            System.out.println(s4.charAt(i));
        }
    }
}

3.3 StringBuilder 添加和反转

链式编程
public class StringBuliderDemo02 {
    public static void main(String[] args) {
        //创建对象
        StringBuilder s = new StringBuilder();

        //public StringBuilder oppend(任意类型):添加数据 并返回对象本身
//        StringBuilder s2=s.append("hello");
//
//        System.out.println("s:"+s);
//        System.out.println("s2:"+s2);
//        System.out.println(s==s2);

//        s.append("hello");
//        s.append("world");
//        s.append("java");
//        s.append(100);

        //链式编程
        s.append("hello ").append("world ").append("Java ").append(100);
        //s:hello world Java 100
        System.out.println("s:" + s);

        //public StringBuilder reverse():返回相反的字符序列
        s.reverse();
        //s:001 avaJ dlrow olleh
        System.out.println("s:" + s);


    }
}

3.4 StringBuilder 和String相互转换

1.StringBuilder转换为String
public String toString():通过toString()就可以实现把StringBuilder转换为String
2. String转换为StringBuilder
public StringBuilder(String s):通过构造方法就可以实现把String转换为StringBuilder

public class StringBuilderDemo03 {
    public static void main(String[] args) {
        //StringBuilder转换为 String
        StringBuilder s=new StringBuilder();
        s.append("hello");
        System.out.println(s);

        String s1=s.toString();
        System.out.println(s1);

        //String 转换为 StringBuilder
        String s2="hello";

        StringBuilder s3=new StringBuilder(s2);
        System.out.println(s3);

    }
}
StringBuilder 案例:拼接字符串

需求: 定义一个方法,把int数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。例如,数组为int[] arr={1,2,3};,执行方法后的输出结果为:[1,2,3]

思路:
① 定义一个int类型的数组,用静态初始化完成数组元素的初始化
② 定义一个方法,用于把int数组中的数据按照指定格式拼接成一个字符串返回,返回值类型String,参数列表int[] arr
③ 在方法中用StringBuilder按照要求进行拼接,并把结果转成String返回
④ 调用方法,用一个变量接收结果
⑤ 输出结果

public class StringBuilderTest01 {
    public static void main(String[] args) {
        //① 定义一个int类型的数组,用静态初始化完成数组元素的初始化
        int[] arr={1,2,3};
       // ④ 调用方法,用一个变量接收结果
        String s = arrayToString(arr);
        System.out.println("s:"+s);
    }

    //② 定义一个方法,用于把int数组中的数据按照指定格式拼接成一个字符串返回,返回值类型String,参数列表int[] arr
        /*
        两个明确:
            返回值类型:String
            参数: int[] arr
         */
        public static String arrayToString(int[] arr){
            //③ 在方法中用StringBuilder按照要求进行拼接,并把结果转成String返回
            StringBuilder s=new StringBuilder();
            s.append("[");
            for (int i=0;i<arr.length;i++){
                if (i==arr.length-1){
                    s.append(arr[i]);
                }else{
                    //拼接
                    s.append(arr[i]).append(",");
                }
            }
            s.append("]");
            String s1=s.toString();
            return s1;
        }
}
StringBuilder 案例:字符串反转

需求: 定义一个方法,实现字符串反转。键盘录入一个字符串,调用该方法后,在控制台输出结果
例如,键盘录入abc,输出结果cba

思路:
① 键盘录入一个字符串,用 Scanner 实现
② 定义一个方法,实现字符串反转,返回值类型 String,参数 String s
③ 在方法中用 StringBuilder 实现字符串的反转,并把结果转成 String 返回
④ 调用方法,用一个变量接收结果
⑤ 输出结果

3.5 通过帮助文档查看 StringBuilder 中的方法

方法名说明
public StringBuilder append(任意类型)添加数据,并返回对象本身
public StringBuilder reverse()返回相反的字符序列
public String toString()通过toString()就可以实现把StringBuilder转换为String
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值