003 String、StringBuffer、StringBuilder

String

在Java中,String类是不可变的,这意味着一旦创建了一个字符串对象,就不能修改其内容。每当对字符串进行修改操作时,实际上是创建了一个新的字符串对象。这种设计是为了确保字符串的不可变性,以提高性能和安全性。

构造方法

这些是String类的一些常用构造方法,更多的方法可见Java的在线文档。

// String():创建一个空字符串对象。
String str = new String();

// String(String original):通过将指定的字符串复制一份来创建一个新的字符串对象。
String str = new String("Hello");

// String(char[] value):通过字符数组创建一个新的字符串对象。
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String str = new String(chars);

// String(char[] value, int offset, int count):通过字符数组的指定部分创建一个新的字符串对象offset表示起始索引,count表示要复制的字符数量。
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String str = new String(chars, 1, 3); // 结果为 "ell"

// String(byte[] bytes):通过字节数组创建一个新的字符串对象,使用默认的字符集解码字节数组。
byte[] bytes = {72, 101, 108, 108, 111};
String str = new String(bytes); // 结果为 "Hello"

// String(byte[] bytes, int offset, int length):通过字节数组的指定部分创建一个新的字符串对象,使用默认的字符集解码字节数组。offset表示起始索引,length表示要复制的字节数量。
byte[] bytes = {72, 101, 108, 108, 111};
String str = new String(bytes, 1, 3); // 结果为 "ell"

// 通过直接赋值一个常量字符串创建一个新的字符串对象。
String str = "Hello";

String 类对象之间的比较 

字符串的比较是一种常见的操作,在Java中提供了四种字符串的比较方式:

// equals()方法用于比较两个字符串的内容是否相等。它是在Object类中定义的,因此所有的Java对象都可以使用该方法。在String类中,equals()方法已经被重写,以便比较字符串的内容而不是引用
String str1 = "Hello";
String str2 = "World";
if (str1.equals(str2)) {
    System.out.println("Strings are equal.");
} else {
    System.out.println("Strings are not equal.");
}

// compareTo()方法用于比较两个字符串的大小关系。它是在Comparable接口中定义的,String类实现了Comparable接口,因此可以使用该方法进行比较。compareTo()方法返回一个整数值,表示字符串之间的比较结果。
String str1 = "Apple";
String str2 = "Banana";
int result = str1.compareTo(str2);
if (result < 0) {
    System.out.println("str1 is less than str2.");
} else if (result > 0) {
    System.out.println("str1 is greater than str2.");
} else {
    System.out.println("str1 is equal to str2.");
}

// equalsIgnoreCase()方法用于比较两个字符串的内容是否相等,但忽略大小写
String str1 = "Hello";
String str2 = "hello";
if (str1.equalsIgnoreCase(str2)) {
    System.out.println("Strings are equal (ignoring case).");
} else {
    System.out.println("Strings are not equal.");
}

// ==运算符用于比较两个字符串对象的引用是否相等。它判断两个字符串对象是否指向同一个内存地址。如果两个字符串对象引用的是同一个对象,则返回true,否则返回false。
String str1 = "Hello";
String str2 = "Hello";
if (str1 == str2) {
    System.out.println("References are equal.");
} else {
    System.out.println("References are not equal.");
}

 需要注意的是,对于字符串的比较,通常使用equals()方法进行内容比较,而不是使用==运算符比较引用。因为==运算符比较的是对象的引用,而不是内容,只有在比较字符串的引用时才会使用==运算符。对于字符串的内容比较,应该使用equals()方法。

字符串查找

这些方法可以用于替换字符串中指定的字符、子字符串或模式匹配项,并返回替换后的新字符串。

// indexOf(String str):返回指定子字符串在原字符串中第一次出现的索引位置。如果找不到子字符串,则返回-1。
String str = "Hello, World!";
int index = str.indexOf("World");
System.out.println("Index of 'World': " + index); // 输出:Index of 'World': 7

// indexOf(String str, int fromIndex):从指定的起始索引位置开始,在原字符串中查找指定子字符串的第一次出现位置。
String str = "Hello, World!";
int index = str.indexOf("o", 5);
System.out.println("Index of 'o' starting from index 5: " + index); // 输出:Index of 'o' starting from index 5: 8

// lastIndexOf(String str):返回指定子字符串在原字符串中最后一次出现的索引位置。如果找不到子字符串,则返回-1。
String str = "Hello, World!";
int lastIndex = str.lastIndexOf("o");
System.out.println("Last index of 'o': " + lastIndex); // 输出:Last index of 'o': 8

// lastIndexOf(String str, int fromIndex):从指定的起始索引位置开始,从后往前在原字符串中查找指定子字符串的最后一次出现位置。
String str = "Hello, World!";
int lastIndex = str.lastIndexOf("o", 7);
System.out.println("Last index of 'o' starting from index 7: " + lastIndex); // 输出:Last index of 'o' starting from index 7: 4

// startsWith(String prefix):检查原字符串是否以指定的前缀开头,返回布尔值。
String str = "Hello, World!";
boolean startsWithHello = str.startsWith("Hello");
System.out.println("Starts with 'Hello': " + startsWithHello); // 输出:Starts with 'Hello': true

// endsWith(String suffix):检查原字符串是否以指定的后缀结尾,返回布尔值。
String str = "Hello, World!";
boolean endsWithWorld = str.endsWith("World!");
System.out.println("Ends with 'World!': " + endsWithWorld); // 输出:Ends with 'World!': true

// charAt(int index):返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常。
String str = "Hello, World!";
char ch = str.charAt(1);
System.out.println(ch); // 输出:e

字符串的转换

这些方法可以用于将字符串与其他数据类型进行转换,或者对字符串进行大小写转换、去除空白字符等操作。它们提供了灵活的字符串转换功能,帮助处理字符串与其他数据类型之间的转化需求。

// toCharArray():将字符串转换为字符数组,返回一个新的char[]数组。
String str = "Hello";
char[] charArray = str.toCharArray();
System.out.println(charArray); // 输出:Hello

// getBytes():将字符串转换为字节数组,使用默认的字符集编码。
String str = "Hello";
byte[] byteArray = str.getBytes();
System.out.println(Arrays.toString(byteArray)); // 输出:[72, 101, 108, 108, 111]

// toLowerCase():将字符串中的所有字符转换为小写形式,返回一个新的字符串。
String str = "Hello";
String lowercase = str.toLowerCase();
System.out.println(lowercase); // 输出:hello

// toUpperCase():将字符串中的所有字符转换为大写形式,返回一个新的字符串。
String str = "Hello";
String uppercase = str.toUpperCase();
System.out.println(uppercase); // 输出:HELLO

// trim():去除字符串开头和结尾的空白字符(空格、制表符、换行符等),返回一个新的字符串。
String str = "  Hello  ";
String trimmed = str.trim();
System.out.println(trimmed); // 输出:Hello

// valueOf():将其他类型的数据转换为字符串。valueOf()是一个静态方法,可以通过类名直接调用。它接受不同类型的参数,包括基本数据类型和对象类型,返回相应类型的字符串表示。
int num = 42;
String str = String.valueOf(num);
System.out.println(str); // 输出:42

boolean flag = true;
String boolStr = String.valueOf(flag);
System.out.println(boolStr); // 输出:true

字符串替换

这些方法可以用于替换字符串中指定的字符、子字符串或模式匹配项,并返回替换后的新字符串。

// replace(char oldChar, char newChar):将字符串中所有的指定字符 oldChar 替换为新的字符 newChar,并返回替换后的新字符串。
String str = "Hello, World!";
String replaced = str.replace('o', '0');
System.out.println(replaced); // 输出:Hell0, W0rld!

// replace(CharSequence target, CharSequence replacement):将字符串中所有的指定子字符串 target 替换为新的子字符串 replacement,并返回替换后的新字符串。CharSequence是一个接口,String类实现了该接口,因此可以接受字符串作为参数。
String str = "Hello, World!";
String replaced = str.replace("World", "Java");
System.out.println(replaced); // 输出:Hello, Java!

// replaceAll(String regex, String replacement):使用正则表达式 regex 匹配字符串中的内容,并将匹配到的部分替换为指定的字符串 replacement,并返回替换后的新字符串。正则表达式可以用于更复杂的模式匹配和替换。
String str = "Hello, 123 World!";
String replaced = str.replaceAll("\\d", "*");
System.out.println(replaced); // 输出:Hello, *** World!

// replaceFirst(String regex, String replacement):使用正则表达式 regex 匹配字符串中的第一个匹配项,并将其替换为指定的字符串 replacement,并返回替换后的新字符串。
String str = "Hello, World!";
String replaced = str.replaceFirst("o", "O");
System.out.println(replaced); // 输出:HellO, World!

 字符串拆分

这些方法可以根据指定的分隔符或正则表达式将字符串拆分成多个子字符串,并返回拆分后的结果。

// split(String regex):根据正则表达式 regex 将字符串拆分成子字符串数组,并返回拆分后的结果。拆分时将字符串按照匹配正则表达式的部分进行分割。
String str = "Hello, World!";
String[] parts = str.split(", ");
System.out.println(Arrays.toString(parts)); // 输出:[Hello, World!]

// split(String regex, int limit):根据正则表达式 regex 将字符串拆分成子字符串数组,并返回拆分后的结果。拆分时将字符串按照匹配正则表达式的部分进行分割。limit 参数指定了拆分的限制,即最多拆分出多少个子字符串。如果超过限制,剩余的部分将作为最后一个元素包含在结果中。
String str = "one,two,three,four,five";
String[] parts = str.split(",", 3);
System.out.println(Arrays.toString(parts)); // 输出:[one, two, three,four,five];

 字符串截取

这些方法可以根据指定的索引或正则表达式来截取字符串的特定部分,并返回截取后的新字符串或拆分后的子字符串数组。

// substring(int beginIndex):从指定的索引位置开始截取字符串,截取从 beginIndex 到字符串末尾的部分,并返回截取后的新字符串。
String str = "Hello, World!";
String substr = str.substring(7);
System.out.println(substr); // 输出:World!

// substring(int beginIndex, int endIndex):截取字符串中从 beginIndex 开始到 endIndex(不包括 endIndex)之间的部分,并返回截取后的新字符串。
String str = "Hello, World!";
String substr = str.substring(7, 12);
System.out.println(substr); // 输出:World

// split(String regex):根据正则表达式 regex 将字符串拆分成子字符串数组,并返回拆分后的结果。拆分时将字符串按照匹配正则表达式的部分进行分割。
String str = "Hello, World!";
String[] parts = str.split(", ");
System.out.println(parts[0]); // 输出:Hello
System.out.println(parts[1]); // 输出:World!

StringBuffer

StringBuffer是一种可变的字符串类,即在创建StringBuffer对象后,我们还可以随意修改字符串的内容。每个StringBuffer的类对象都能够存储指定容量的字符串,如果字符串的长度超过了StringBuffer对象的容量空间,则该对象的容量会自动扩大。另外我们在使用StringBuffer类时,比如每次调用toString()方法,都会直接使用缓存区的toStringCache 值来构造一个字符串,这每次都是对StringBuffer对象本身进行操作,而不会重新生成一个新对象。所以如果我们需要对大量字符串的内容进行修改,推荐大家使用StringBuffer。

常用方法

// append(String str):将指定的字符串追加到当前字符串的末尾。
StringBuffer sb = new StringBuffer("Hello");
sb.append(", World!");
System.out.println(sb.toString()); // 输出:Hello, World!

// insert(int offset, String str):在指定的偏移量位置插入指定的字符串。
StringBuffer sb = new StringBuffer("Hello");
sb.insert(5, ", World!");
System.out.println(sb.toString()); // 输出:Hello, World!

// replace(int start, int end, String str):用指定的字符串替换从指定起始位置到结束位置的子字符串。
StringBuffer sb = new StringBuffer("Hello, World!");
sb.replace(7, 12, "Java");
System.out.println(sb.toString()); // 输出:Hello, Java!

// delete(int start, int end):删除从指定起始位置到结束位置的子字符串。
StringBuffer sb = new StringBuffer("Hello, World!");
sb.replace(7, 12, "Java");
System.out.println(sb.toString()); // 输出:Hello, Java!

// reverse():反转当前字符串。
StringBuffer sb = new StringBuffer("Hello");
sb.reverse();
System.out.println(sb.toString()); // 输出:olleH

StringBuilder

要想实现可变字符串的操作,其实还有另一个StringBuilder类,该类是在Java 5中被提出的。它和 StringBuffer的基本用法几乎是完全一样的,关于StringBuilder的用法,这里就先不讲解太多了。StringBuilder和StringBuffer最大的不同在于,StringBuilder的各个方法都不是线程安全的(不能同步访问),在多线程时可能存在线程安全问题,但StringBuilder的执行效率却比StringBuffer快的多。

String、StringBuffer 和 StringBuilder 之间的区别

在Java中,String、StringBuffer和StringBuilder是用于操作字符串的三个类,它们之间有以下区别:

不可变性

String是不可变的,一旦创建就不能修改,任何对String的操作都会创建新的字符串对象。
StringBuffer和StringBuilder是可变的,允许对字符串进行动态修改。StringBuffer是线程安全的,而StringBuilder是非线程安全的。

线程安全性

String是不可变的,因此在多线程环境下是线程安全的。
StringBuffer是线程安全的,它的方法使用了同步机制来保证线程安全性。
StringBuilder是非线程安全的,它的方法没有同步机制,适用于单线程环境。

性能

String的不可变性带来了一些性能优化,例如字符串常量池和缓存的哈希值。然而,频繁的字符串拼接和修改会导致大量的临时对象创建,性能较低。
StringBuffer和StringBuilder的可变性使得字符串的操作更高效,避免了不必要的对象创建和拷贝。由于StringBuffer的线程安全性,它在性能上可能稍慢于StringBuilder。

适用场景

String适用于字符串不需要修改的情况,例如常量、参数传递等。
StringBuffer适用于多线程环境或需要线程安全的场景,例如多线程共享字符串的修改。
StringBuilder适用于单线程环境,不需要线程安全的场景,例如字符串的拼接、修改等操作。


综上所述,String适用于不需要修改的字符串,StringBuffer适用于多线程环境或需要线程安全的字符串操作,StringBuilder适用于单线程环境下的字符串操作。根据具体的需求和性能要求,选择适合的类来操作字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值