Java中的String、StringBuffer和StringBuilder

本文探讨了Java中的String类特点,包括其不可变性、共享性及底层实现。接着介绍了StringBuffer和StringBuilder,两者同样基于字符数组,但支持字符串的修改。StringBuffer线程安全,适合多线程环境,而StringBuilder效率更高,适用于单线程。在选择使用时,应根据实际需求权衡修改频率和线程安全因素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

String        

      在熟背的八大数据类型中,String是不存在的;String表示字符串类型,属于 引用数据类型,不属于基本数据类型。

String类的特点

  • 字符串不可变,它们的值在创建后不能被更改

  • 虽然 String 的值是不可变的,但是它们可以被共享

  • 字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )

String类的构造方法

  • 常用的构造方法
public String()创建一个空白字符串对象,不含有任何内容
public String(char[] chs)根据字符数组的内容,来创建字符串对象
public String(byte[] bys)根据字节数组的内容,来创建字符串对象
String s = “abc”;直接赋值的方式创建字符串对象,内容就是abc
 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};
        String s3 = new String(bys);
        System.out.println("s3:" + s3);

        //String s = “abc”;	直接赋值的方式创建字符串对象,内容就是abc
        String s4 = "abc";
        System.out.println("s4:" + s4);
    }

        String类提供了许多的方法对字符串进行操作

charAt(int index)
          返回指定索引处的 char 值。
concat(String str)
          将指定字符串连接到此字符串的结尾。
contains(CharSequence s)
          当且仅当此字符串包含指定的 char 值序列时,返回 true。
endsWith(String suffix)
          测试此字符串是否以指定的后缀结束。
equals(Object anObject)
          将此字符串与指定的对象比较。
getBytes()
          使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
          将字符从此字符串复制到目标字符数组。
hashCode()
          返回此字符串的哈希码。
indexOf(int ch)
          返回指定字符在此字符串中第一次出现处的索引。
lastIndexOf(int ch)
          返回指定字符在此字符串中最后一次出现处的索引。
lastIndexOf(String str, int fromIndex)
          返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
length()
          返回此字符串的长度。
replace(char oldChar, char newChar)
          返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
split(String regex)
          根据给定正则表达式的匹配拆分此字符串。
startsWith(String prefix)
          测试此字符串是否以指定的前缀开始。
substring(int beginIndex, int endIndex)
          返回一个新字符串,它是此字符串的一个子字符串。
toLowerCase()
          使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
toUpperCase()
          使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
trim()
          返回字符串的副本,忽略前导空白和尾部空白。
valueOf(Object obj)
          返回 Object 参数的字符串表示形式。

方法的具体演示: 

String str="123456abc";

String str1=new String("123456abc");

System.out.println(str.equals("123abcd"));//打印为false

System.out.println(str.equals("123456abc"));//打印为true

System.out.println(str.length());//打印为9

System.out.println(str.charAt(1));//打印为2

System.out.println(str.indexOf("3"));//打印为2

System.out.println(str.indexOf("3"));//打印为2

 char[] chars = str.toCharArray();
  for (int i=0;i<chars.length;i++){
      System.out.println(chars[i]);
  }//输出结果为一个字符一行的打印

String sr="Signal-strength";
  String s = sr.toUpperCase();
  System.out.println(s);//打印为SIGNAL-STRENGTH

String sr="Signal-strength";
  String s = sr.toLowerCase();
  System.out.println(s);//打印为signal-strength

  String str="123_456";
  String[] s = str.split("_");  
  for (String s1:s){
      System.out.println(s1);
  }
//打印为
// 123
// 456

String str=" 1 23_456 ";
System.out.println(str);
System.out.println(str.trim());

String str="123_456";
System.out.println(str.substring(0,3));//不包含3
System.out.println(str.substring(2));//从第3个位置截取

String str="absC";
String str1="absc";
System.out.println(str.concat(str1));//打印为absCabsc

String str="absCac";
System.out.println(str.startsWith("ab"));//打印为true

String str="absCac";
System.out.println(str.startsWith("ab"));//打印为true

String s = String.valueOf(21);
System.out.println(s);//打印为21

 StringBuffer和StringBuilder

        StringBuffer、StringBuilder和String类似,底层也是用一个数组来存储字符串的值,并且数组的默认长度为16,即一个空的StringBuffer对象数组长度为16。实例化一个StringBuffer对象即创建了一个大小为16个字符的字符串缓冲区。但是​当我们调用有参构造函数创建一个StringBuffer对象时,数组长度就不再是16了,而是根据当前对象的值来决定数组的长度,数组的长度为“当前对象的值的长+16”。所以一个 StringBuffer 创建完成之后,有16个字符的空间可以对其值进行修改。如果修改的值范围超出了16个字符,会先检查StringBuffer对象的原char数组的容量能不能装下新的字符串,如果装不下则会对 char 数组进行扩容。

那StringBuffer是怎样进行扩容的呢?
        扩容的逻辑就是创建一个新的 char 数组,将现有容量扩大一倍再加上2,如果还是不够大则直接等于需要的容量大小。扩容完成之后,将原数组的内容复制到新数组,最后将指针指向新的 char 数组。

StringBuffer和StringBuilder中常用的方法:

StringBuffer append(xxx):拼接字符串
StringBuffer delete(int start,int end):删除指定范围的内容,左开右闭
StringBuffer replace(int start, int end, String str):替换指定范围的内容
StringBuffer insert(int offset, xxx):在指定位置插入指定的内容
StringBuffer reverse() :把当前字符序列逆转

public int indexOf(String str) : 返回指定子字符串在当前字符串中第一次出现处的索引
public String substring(int start,int end) :返回指定范围的子字符串
public int length() : 返回字符串的长度
public char charAt(int n ) : 获取指定索引处的字符
public void setCharAt(int n ,char ch) : 设置指定索引处的字符

 StringBuilder str = new StringBuilder("我是");
//    拼接字符串
        str.append("美女");
        System.out.println(str);
//    添加字符串
        str.insert(2,"超级");
        System.out.println(str);
//    颠倒
//    str.reverse();
        System.out.println(str);
//    删除从2-4(不包括4)
        str.delete(2,4);
        System.out.println(str);
//    将下标为2的字符改为“=”
        str.setCharAt(2,'=');
        System.out.println(str);

String、StringBuffer和StringBuilder的异同?

        相同点:底层都是通过char数组实现的

        不同点:

1、String对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的;


2、StringBuffer几乎所有的方法都使用synchronized实现了同步,线程比较安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder 没有实现同步,线程不安全,在多线程系统中不能使用 StringBuilder,但是效率比较高。


3、如果我们在实际开发过程中需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费;当需要考虑线程安全的场景下使用 StringBuffer,如果不需要考虑线程安全,追求效率的场景下可以使用 StringBuilder。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晗晗想吃烤鱼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值