java中的String类与StringBuffer类

每日一言

Just what is right and what is wrong…? To begin with, just who is the enemy I must defeat? – Rentaro Satomi
from Black Bullet

String类创建

String类的构造方法有11种,我们这里了解两种最基本的创建方法:

1
2
3
String str1 = "ulna";		//直接构造String类
char[] arry = ['u','l','n','a'];
String str2 = new String(arry); //将char数组转化为String类

在java中,双引号括起来的文本(如 "Hello World")被称为 字符串字面量 ,它们会被自动视为 String 类型的对象。

String类的不可变性

Java中的String类低层封装时是通过一个 final 的字符数组(char()) 实现的,导致这个数组的内容在对象创建后不能被修改。任何对于String的修改操作都会创建一个新的String类。

验证不可变性:

1
2
3
4
5
6
7
8
9
public class Test{
public static void main(String[] args){
String str = "Hello";
String str1 = str;
str += " World";
System.out.println(str1);
System.out.println(str);
}
}

运行结果:

1
2
Hello
Hello World

创建格式化字符串

如果要输出格式化字符串,可以使用 System.out.printf()函数:

1
2
3
4
System.out.printf("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
" %s", floatVar, intVar, stringVar);

如果想要创建可以复用的String类的格式化字符串,可以使用 .format() 方法:

1
2
3
4
5
String fs;
fs = String.format("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
" %s", floatVar, intVar, stringVar);

String中的常用方法

  1. 获取字串

    1
    2
    3
    4
    String str1 = "abcdef";
    String str2 = str1.substring( 0, 3); //获取下标[0,3)的字符组成的字串:abc
    String str3 = str1.substring(3); //获取下标[3,)的字串: def

  2. 连接字符串

    1
    2
    3
    4
    String str1 = "hello";
    String str2 = " world";
    String str3 = str1.concat(str2); //使用contact方法
    String str4 = str1 + str2; //使用+相连

    主要差别:

    特性 concat() + 运算符
    参数类型 只能拼接 String 类型,其他类型会报错。 可以拼接任意类型,会自动转换为字符串。调用toString()
    null 的处理 如果参数是 null,会抛出 NullPointerException 如果参数是 null,会将其视为字符串 "null"
    性能 性能稍高,因为直接操作字符串对象。 性能稍低,可能涉及 StringBuilder 的隐式调用。
    代码可读性 可读性稍差,适合明确的字符串拼接操作。 可读性更高,代码更简洁。
  3. 比较字典序

    1
    2
    3
    4
    5
    6
    7
    String str1 = "a";
    String str2 = "b";
    String str3 = "c";
    String str4 = "b";
    System.out.println(str2.compareTo(str1)); //当str2大于str1时,返回正数
    System.out.println(str2.compareTo(str3)); //当str2小于str3时,返回负数
    System.out.println(str2.compareTo(str4)); //当str2等于str4时,返回0
  4. 通过下标获取字符

    1
    2
    3
    4
    5
    String str1 = "abcd";
    System.out.println(str1.charAt(0)); //a
    System.out.println(str1.charAt(1)); //b
    System.out.println(str1.charAt(2)); //c
    System.out.println(str1.charAt(3)); //d
  5. 前缀判断

    1
    2
    3
    String str1 = "abcd";
    str1.startsWith("ab") //判断字符串是否以ab开头
    str1.startsWith("ab",1) //从下标1开始的字串是否以ab开头
  6. 后缀判断

    1
    2
    String str1 = "abcd";
    str1.endsWith("cd") //检查后缀是否为cd。只有这一个版本
  7. 查找指定字串第一次出现的位置

    1
    2
    3
    String str1 = "aabcd";
    str1.indexOf("bc"); //返回bc第一次出现的下标:2
    str1.indexOf("bc", 3); //从下标3开始的部分中bc第一次出现的下标:-1(没找到返回-1)
  8. 查找指定字串最后一次出现的位置

    1
    2
    3
    String str1 = "abcabcd";
    str1.lastIndexOf("bc") //返回bc在字符串中最后一次出现的下标:4
    str1.lastIndexOf("bc", 3) //从下标3开始反向搜索:1 (未找到返回-1)
  9. 判断字符串是否相等

    1
    2
    3
    4
    String str1 = "aabcd";
    String str2 = "abcd";
    boolean isEqual = str1.equals(str2); //判断str1和str2的内容是否相等
    str1 == str2; // 比较对象的引用是否相等

其他String类的方法可以参见:Java String 类 | 菜鸟教程

StringBuffer类

在上面的演示中,由于Sting类的不可修改性,在每次对于String对象进行修改时,都会产生一个新的String对象,这显然是不高效的。

StringBuffer类正是用于解决这一问题。如果你需要对于一个字符串进行多次修改,使用StingBuffer类会更快,它可以直接在对象本身上修改。

StringBuffer类的创建

StringBuffer 的创建必须使用StringBuffer的构造方法来创建。但是与String类创建时必须直接赋值不同。StringBuffer类有三种构造方式

1
2
3
StringBuffer str1 = new StringBuffer("Hello");	//传入字符串字面量
StringBuffer str2 = new StringBuffer(10); //传入int类型,指定初始容量
StringBuffer str3 = new StringBuffer(); //创建一个空StringBuffer实例

StringBuffer类在容量不够时会自动扩充容量:假设现在的容量为x

  • 比较2x+2与字符串长度的大小
    • 如果2x+2更大,则创建一个容量为2x+2大小的char[]
    • 否则创建一个和字符串长度相等的char[]
  • 将旧数组的内容复制到新数组中
  • 用新数组替换旧数组

我们看以下示范代码:

1
2
3
4
5
6
7
8
StringBuffer str = new StringBuffer();
System.out.println(str.capacity());
str.append("abcdefghijklmnopqrstuvwxyz"); // 26 characters
System.out.println(str.capacity());
str.append("abcdefghijklmnopqrstuvwxyz"); // 52 characters
System.out.println(str.capacity());
str.append("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); //156 characters
System.out.println(str.capacity());

运行结果如下:

1
2
3
4
16	//初始时容量为16
34 //添加24个字母后容量为16*2+2
70 //再添加24个字母后容量为34*2+2
156 //添加到156个字母,大于70*2+2故直接创建一个156的数组

虽然StringBuffer会自动扩容,但是频繁扩容会影响性能。因此如果预先知道大致需要的容量,最好在创建时就指定合适的初始容量。

StringBuffer的编辑方法

我们知道创建StringBuffer就是因为我们需要大量的编辑这个字符串,接下来我们来看看有哪些方法可以编辑StringBuffer实例

  1. 在末尾添加字串

    1
    2
    StringBuffer str = new StringBuffer(); 
    str.append("abcdefghijklmnopqrstuvwxyz"); // append方法会将指定的字符串添加到末尾
  2. 将字符串反转

    1
    2
    3
    StringBuffer str = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
    str.reverse(); //reverse()会直接将字符串反转
    System.out.println(str); // Output: zyxwvutsrqponmlkjihgfedcba
  3. 删除一段

    1
    2
    3
    StringBuffer str = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
    str.delete(0, 1); //删除范围在[0,1)之间的字符串
    System.out.println(str); // Output: bcdefghijklmnopqrstuvwxyz
  4. 在字符串中插入

    1
    2
    3
    StringBuffer str = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
    str.insert(2, "123"); // 在下标为2的位置插入,后续的字符串全部后移
    System.out.println(str); // Output: ab123cdefghijklmnopqrstuvwxyz
  5. 替代

    1
    2
    3
    StringBuffer str = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
    str.replace(1, 3, "12345456789"); //将指定下标的内容替换为指定的字符串,长度可以不一
    System.out.println(str); // Output: a12345456789defghijklmnopqrstuvwxyz

除了以上修改专门的方法以外,StringBuffer类还有很多与String都有的函数,可以参考:Java StringBuffer 和 StringBuilder 类 | 菜鸟教程

StringBulider类

StringBuilder类与StringBuffer类差别为:

  • StringBulider 类性能更好,但是不是线程安全的
  • StringBuffer 类是线程安全的,可以多线程同步访问

因此在单线程时,可以通过使用StringBuilder类来提高性能


java中的String类与StringBuffer类
http://blog.ulna520.com/2025/03/24/java中的String类_20250324_191053/
Veröffentlicht am
March 24, 2025
Urheberrechtshinweis