String、StringBuffer、StringBuilder的区别

String、StringBuffer、StringBuilder的区别

1. String 类

  • String 对象用于保存字符串,也就是一组字符序列
  • 字符串常量对象使用**双引号(" ")**括起的字符序列。例如:“xjz”、"2002"等
  • 字符串的字符使用Unicode编码,一个字符(不区分字母还是汉字)占两个字节
  • String类较常用构造器(其他看手册)
String s1 = new String();
String s2 = new String(String original);
String s3 = new String(char[] a);
String s4 = new String(char[] a,int startIndex,int count);

image-20230912100346685

1.1 创建String对象的两种方式

  1. 方式一:直接赋值 String s = “xjz2002”;
  2. 方式二:调用构造器 String s2 = new String(“xjz2002”);
  • 方式一:先从常量池查看是否有"xjz2002"数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址

  • 方式二:现在堆中创建空间,里面维护了value属性,指向常量池的xjz2002空间。如果常量池中没有"xjz2002",重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。

  • 画出两种方式的内存分布

    image-20230912101838202

1.2 String 类的常见方法

String类是保存字符串常量的。每次更新都需要重新开辟空间,效率较低,因此java设计者还提供了 StringBuilderStringBuffer 来增强String的功能,并提高效率。

image-20230912102045439

package com.xjz.string;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class StringMethod01 {
    public static void main(String[] args) {

        //1. equals 前面已经讲过了,比较内容是否相同,区分大小写
        String str1 = "hello";
        String str2 = "Hello";
        System.out.println(str1.equals(str2)); //False

        //2. equalsIgnoreCase 忽略大小写的判断内容是否相等
        String username = "johN";
        if ("john".equalsIgnoreCase(username)){
            System.out.println("Success!");
        } else {
            System.out.println("Failure!");
        }

        //3. length 获取字符的个数,字符串的长度
        System.out.println("徐金卓".length());

        //4. indexOf 获取字符在字符串对象中第一次出现的索引,索引从 0 开始,如果找不到,返回 -1
        String s1 = "wer@terwe@g";
        int index = s1.indexOf('@');
        System.out.println(index); //3
        System.out.println("weIndex = " + s1.indexOf("we")); //0

        //5. lastIndexOf 获取字符在字符串中最后一次出现的索引,索引从 0 开始,如果找不到,返回 -1
        s1 = "wer@terwe@g@";
        index = s1.lastIndexOf('@');
        System.out.println(index);//11
        System.out.println("ter 的位置=" + s1.lastIndexOf("ter"));//4

        //6. substring 截取指定范围的子串
        String name = "hello,张三";
        //下面 name.substring(6) 从索引 6开始截取后面所有内容
        System.out.println(name.substring(6));

        //下面 name.substring(2,5) 从索引 2 开始,截取到 4 即llo
        //左闭右开区间 [2,5)
        System.out.println(name.substring(2,5));
    }
}

image-20230912102305625

package com.xjz.string;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class StringMethod02 {
    public static void main(String[] args) {

        //1. toUpperCase 转换成大写
        String s = "heLLo";
        System.out.println(s.toUpperCase()); //HELLO

        //2. toLowerCase
        System.out.println(s.toLowerCase()); //hello

        //3. concat拼接字符串
        String s1 = "宝玉";
        s1 = s1.concat("林黛玉").concat("together");
        System.out.println(s1); //宝玉林黛玉together

        //4. replace 替换字符串中的字符
        s1 = "宝玉 and 林黛玉 林黛玉 林黛玉";
        //在 s1 中,将 所有的 林黛玉 替换成薛宝钗
        // 老韩解读: s1.replace() 方法执行后,返回的结果才是替换过的.
        // 注意对 s1 没有任何影响
        String s2 = s1.replace("林黛玉", "xjz");
        System.out.println(s1); //宝玉 and 林黛玉 林黛玉 林黛玉
        System.out.println(s2); //宝玉 and xjz xjz xjz

        //5. split 分隔字符串,对于某些分割字符,我们需要 转义比如 | \\ 等
        String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
        // 老师解读:
        // 1. 以 , 为标准对 poem 进行分割,返回一个数组
        // 2. 在对字符串进行分割时,如果有特殊字符,需要加入 转义符 \
        String[] split = poem.split(",");
        poem = "E:\\aaa\\bbb";
        split = poem.split("\\\\");
        System.out.println("===分割后内容===");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }

        //6. toCharArray 转换成字符数组
        s = "happy";
        char[] chs = s.toCharArray();
        for (int i = 0; i < chs.length; i++) {
            System.out.println(chs[i]);
        }

        //7. compareTo 比较两个字符串的大小,如果前者大,
        // 则返回正数,后者大,则返回负数,如果相等,返回 0
        // (1) 如果长度相同,并且每个字符也相同,就返回 0
        // (2) 如果长度相同或者不相同,但是在进行比较时,可以区分大小
        // 就返回 if (c1 != c2) {
        // return c1 - c2;
        // }
        // (3) 如果前面的部分都相同,就返回 str1.len - str2.len
        String a = "jac"; //len = 3
        String b = "jack"; //len = 4
        System.out.println(a.compareTo(b));//-1
    }
}

2. StringBuffer 类

  • java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删
  • 很多方法与String相同,但StringBuffer是可变长度的。
  • StringBuffer 是一个容器

2.1 String VS StringBuffer

1) String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上是更改地址,效率极地 // private final char value[];

2)StringBuffer 保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率极高 // char[] value; //这个放在堆

2.2 String 和 StringBuffer 相互转换

package com.xjz.stringbuffer;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class StringAndStringBuffer {
    public static void main(String[] args) {

        //看 String --》 StringBuffer
        String str = "hello tom";
        //方式1 使用构造器
        //注意:返回的才是 StringBuffer对象,对 str 本身没有影响
        StringBuffer stringBuffer = new StringBuffer(str);

        //方式2 使用的是 append 方法
        StringBuffer stringBuffer1 = new StringBuffer();
        stringBuffer1.append(str);

        //看看 StringBuffer -> String
        StringBuffer stringBuffer2 = new StringBuffer("xjz");
        //方式1 使用 StringBuffer 提供的 toString() 方法
        String s = stringBuffer2.toString();
        //方式2 使用构造器来搞定
        String s1 = new String(stringBuffer2);
    }
}

2.3 StringBuffer 类常见方法

package com.xjz.stringbuffer;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class StringBufferMethod {
    public static void main(String[] args) {

        StringBuffer sb = new StringBuffer("hello");
        //增
        sb.append(","); //"hello,"
        sb.append("张三丰");//"hello,张三丰"
        sb.append("赵敏").append(100).append(true).append(10.5); //"hello,张三丰赵敏 100true10.5"
        System.out.println(sb);//"hello,张三丰赵敏 100true10.5"

        //删
        /*
         * 删除索引为>=start && <end 处的字符
         * 解读: 删除 11~14 的字符 [11, 14)
         */
        sb.delete(11,14);
        System.out.println(sb); //hello,张三丰赵敏true10.5

        //改
        // 使用 周芷若 替换 赵敏 即:索引 9-11 的字符 [9,11)
        sb.replace(9,11,"周芷若");
        System.out.println(sb); //hello,张三丰周芷若true10.5

        //查找指定的子串在字符串中第一次出现的索引,如果找不到索引返回 -1
        int indexOf = sb.indexOf("张三丰");
        System.out.println(indexOf); //6

        //插
        // 在索引为 9 的位置插入 “赵敏”,原来索引为 9 的内容自动后移
        sb.insert(9,"赵敏");
        System.out.println(sb); //hello,张三丰赵敏周芷若true10.5

        //长度 length
        System.out.println(sb.length());
        System.out.println(sb);
    }
}

3. StringBuilder 类

1) 一个可变的字符序列,此类提供一个与 StringBuffer 兼容的 API,但不保证同步(StringBuilder 不是线程安全)。该类被设计用做 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的使用。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快

2)在 StringBuilder 上的主要操作是 append 和 insert 方法,可重载这些方法,以接收任意类型的数据。

3.1 StringBuilder 常用方法

StringBuilder 和 StringBuffer 均代表可变的字符序列,方法是一样的,所以使用和StringBuffer一样。

看一下源码

image-20230912103711735

package com.xjz.stringbuilder;
/**
 * @author xjz_2002
 * @version 1.0
 */
public class StringBuilder01 {
    public static void main(String[] args) {
        //1. StringBuilder 继承 AbstractStringBuilder 类
        //2. 实现了 Serializable ,说明 StringBuilder 对象是可以串行化(对象可以网络传输,可以保存到文件)
        //3. StringBuilder 是 final 类, 不能被继承
        //4. StringBuilder 对象字符序列仍然是存放在其父类 AbstractStringBuilder 的 char[] value;
        // 因此,字符序列是堆中
        //5. StringBuilder 的方法,没有做互斥的处理,即没有 synchronized 关键字,因此在单线程的情况下使用
        // StringBuilder
        StringBuilder stringBuilder = new StringBuilder();
    }
}

4. String、StringBuffer 和 StringBuilder 的比较

1)StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法也一样

2)String:不可变字符序列,效率低,但是复用率高。

3)StringBuffer:可变字符序列,效率较高(增删)、线程安全,看源码

4)Stringbuilder:可变字符序列,效率最高,线程不安全

5. String、StringBuffer 和 StringBuilder 的选择

使用原则,结论如下:

  1. 如果字符串存在大量的修改操作,一般使用 StringBuffer 和 StringBuilder
  2. 如果字符串存在大量的修改操作,并在单线程情况下,使用StringBuilder
  3. 如果字符串存在大量的修改操作,并在多线程情况下,使用StringBuffer
  4. 如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等

StringBuilder 的方法和 StringBuffer 一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xjz_2002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值