认识String类
目录
2.StringBuilder 和 StringBuffer的区别
一.String类
1.字符串的构造
字符串的构造方式有很多种,但是我这里就举例三种常用的方式:
//直接使用字符串构造
String s="abc";
System.out.println(s);
//new一个String类对象
String s1=new String("abc");
System.out.println(s1);
//利用char数组来new一个String对象
char[] ch={'a','b','c'};
String s2=new String(ch);
System.out.println(s2);
当然如果想要了解更多,可以访问这个网站查阅:Java Platform SE 8
2.字符串的特点(重点)
2.1不可变性
在 Java 中,
String
类被设计为不可变的,即字符串对象一旦创建,其内容就无法修改。任何试图修改字符串的操作(如拼接、替换等)实际上会创建一个新的字符串对象,而不会更改原来的对象。
比如:
String str1 = "Hello";
String str2 = str1.concat(" World");
// str1仍然是 "Hello",str2是 "Hello World"
解释:调用
concat
方法并没有修改str1
,而是生成了一个新的字符串str2
。
优点:
1.尽管每次修改都会创建新的字符串对象,看似增加了内存开销和处理时间,但 JVM 的优化和垃圾回收机制能够有效管理这些开销。
2.不可变性防止了字符串被不小心或恶意修改。
3.由于字符串是不可变的,可以安全地在多线程环境中共享而不需要同步。
2.2字符串池
字符串池是 JVM 内存中的一个特殊区域,用于存储字符串字面量。在创建字符串时,如果字符串的值已经存在于池中,JVM 会返回池中已有的字符串对象,而不是创建一个新的。这种机制避免了重复的字符串对象,从而节省内存。
比如:
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); // 输出 true
解释:
str1
和str2
都指向同一个字符串池中的对象,因此==
比较返回true
。
字符串池的使用:
String str1 = new String("Hello");
String str2 = str1.intern();
String str3 = "Hello";
System.out.println(str2 == str3); // 输出 true
解释:
字面量创建:使用双引号创建的字符串会被自动放入字符串池中。例如,
String str = "Hello";
会将"Hello"
放入池中。显式创建:通过
new
关键字创建的字符串不会自动加入字符串池。例如,String str = new String("Hello");
会创建一个新的字符串对象,而不是从池中获取。
intern
方法:String
类的intern
方法可以将字符串显式加入字符串池。如果池中已经存在相同值的字符串,则返回池中的引用;否则,将该字符串加入池中,并返回它的引用。
注意事项:
String是引用类型,内部并不存储字符串本身,我们可以查看String类的实现源码:
这样的话不仅提高了内存效率还节省了内存消耗。
与此同时,我们可以看到该数组被final修饰,final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内 容是可以修改的。所有对字符串的操作方法(如
substring
、concat
)都返回新的字符串对象,而不是修改原来的字符串。
public static void main(String[] args) {
// s1和s2引用的是不同对象 s1和s3引用的是同一对象
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
System.out.println(s1.length()); // 获取字符串长度---输出5
System.out.println(s1.isEmpty()); // 如果字符串长度为0,返回true,否则返回false
}
// 打印"hello"字符串(String对象)的长度
System.out.println("hello".length());
3.String对象的比较
3.1使用 ==
运算符
对于基本类型变量,==比较两个变量中存储的值是否相同。
对于引用类型变量,==比较两个引用变量引用的是否为同一个对象。注意:String是引用类型
//基本类型
int a = 10;
int b = 20;
int c = 30;
System.out.println(a == b); // false
System.out.println(a == c); // true
//String引用类型
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println(str1 == str2); // 输出 true
System.out.println(str1 == str3); // 输出 false
3.2使用 equals()
方法
String类重写了父类Object中equals方法,Object中equals默认按照==比较。
equals()
方法比较的是两个字符串对象的内容是否相同。
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println(str1.equals(str2)); // 输出 true
//equals() 方法比较的是 str1 和 str2 的字符序列,它们的内容相同,所以返回 true。
3.3区分大小写的比较
equals()
方法默认是区分大小写的。如果需要忽略大小写进行比较,可以使用equalsIgnoreCase()
方法。
String str1 = "Hello";
String str2 = "hello";
System.out.println(str1.equals(str2)); // 输出 false
System.out.println(str1.equalsIgnoreCase(str2)); // 输出 true
3.4按照字典顺序比较(compareTo(String s)方法)
compareTo()
方法:用于按照字典顺序比较两个字符串。与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型,比较方式:
1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值。
2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值。
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("ac");
String s3 = new String("abc");
String s4 = new String("abcdef");
System.out.println(s1.compareTo(s2)); // 不同输出字符差值-1
System.out.println(s1.compareTo(s3)); // 相同输出 0
System.out.println(s1.compareTo(s4)); // 前k个字符完全相同,输出长度差值 -3
}
3.5compareToIgnoreCase(String str) 方法忽略大小比较
compareToIgnoreCase(String str)
方法和compareTo()
方法差不多,只不过是忽略了大小的比较。
public class CompareToIgnoreCaseExample {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "HELLO";
String str3 = "world";
// 比较 str1 和 str2
int result1 = str1.compareToIgnoreCase(str2);
System.out.println(result1); // 输出 0
// 比较 str1 和 str3
int result2 = str1.compareToIgnoreCase(str3);
System.out.println(result2); // 输出负数
}
}
//str1.compareToIgnoreCase(str2):由于 str1 和 str2 内容相同,但大小写不同,方法忽略了大小写差异,因此返回 0,表示它们相等。
//str1.compareToIgnoreCase(str3):str1 和 str3 内容不同,按照字典顺序比较,"hello" 小于 "world",所以返回负数。
4.字符串查找
方法 | 功能 |
char charAt(int index) | 返回index位置上字符,如果index为负数或者越界,抛出 IndexOutOfBoundsException异常 |
int indexOf(int ch) | 返回ch第一次出现的位置,没有返回-1 |
int indexOf(int ch, int fromIndex) | 从fromIndex位置开始找ch第一次出现的位置,没有返回-1 |
int indexOf(String str) | 返回str第一次出现的位置,没有返回-1 |
int indexOf(String str, int fromIndex) | 从fromIndex位置开始找str第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch) | 从后往前找,返回ch第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch, int fromIndex) | 从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返 回-1 |
int lastIndexOf(String str) | 从后往前找,返回str第一次出现的位置,没有返回-1 |
int lastIndexOf(String str, int fromIndex) | 从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返 回-1 |
public class StringMethodsExample {
public static void main(String[] args) {
String str = "Hello, world!";
// 使用 charAt() 方法
try {
char charAtIndex = str.charAt(4); // 获取索引4的字符
System.out.println("charAt(4): " + charAtIndex); // 输出: o
} catch (StringIndexOutOfBoundsException e) {
System.out.println("Index out of bounds in charAt()");
}
// 使用 indexOf() 方法
int firstIndexOfH = str.indexOf('H'); // 查找字符'H'首次出现的位置
System.out.println("indexOf('H'): " + firstIndexOfH); // 输出: 0
// 使用 indexOf() 方法并指定起始位置
int indexOfOFrom5 = str.indexOf('o', 5); // 从索引5开始查找字符'o'
System.out.println("indexOf('o', 5): " + indexOfOFrom5); // 输出: 8
// 使用 indexOf() 查找子字符串
int indexOfWorld = str.indexOf("world"); // 查找子字符串"world"
System.out.println("indexOf('world'): " + indexOfWorld); // 输出: 7
// 使用 indexOf() 查找子字符串并指定起始位置
int indexOfWorldFrom5 = str.indexOf("world", 5); // 从索引5开始查找子字符串"world"
System.out.println("indexOf('world', 5): " + indexOfWorldFrom5); // 输出: 7
// 使用 lastIndexOf() 方法
int lastIndexOfO = str.lastIndexOf('o'); // 从末尾开始查找字符'o'最后一次出现的位置
System.out.println("lastIndexOf('o'): " + lastIndexOfO); // 输出: 8
// 使用 lastIndexOf() 方法并指定起始位置
int lastIndexOfOFrom5 = str.lastIndexOf('o', 5); // 从索引5向前查找字符'o'
System.out.println("lastIndexOf('o', 5): " + lastIndexOfOFrom5); // 输出: 4
// 使用 lastIndexOf() 查找子字符串
int lastIndexOfWorld = str.lastIndexOf("world"); // 从末尾开始查找子字符串"world"
System.out.println("lastIndexOf('world'): " + lastIndexOfWorld); // 输出: 7
// 使用 lastIndexOf() 查找子字符串并指定起始位置
int lastIndexOfWorldFrom5 = str.lastIndexOf("world", 5); // 从索引5向前查找子字符串"world"
System.out.println("lastIndexOf('world', 5): " + lastIndexOfWorldFrom5); // 输出: 7
}
}
5.转换
5.1 字符串与字符数组的转换
public static void main(String[] args) {
String str = "Hello";
// 将字符串转换为字符数组
char[] charArray = str.toCharArray();
System.out.println("charArray: " + java.util.Arrays.toString(charArray)); // 输出: [H, e, l, l, o]
// 将字符数组转换为字符串
String newStr = new String(charArray);
System.out.println("newStr: " + newStr); // 输出: Hello
}
toCharArray()
:将字符串转换为字符数组。String(char[] value)
:将字符数组转换为字符串。
5.2 字符串与整数的转换
public static void main(String[] args) {
String str = "123";
// 将字符串转换为整数
int num = Integer.parseInt(str);
System.out.println("num: " + num); // 输出: 123
// 将整数转换为字符串
String newStr = String.valueOf(num);
System.out.println("newStr: " + newStr); // 输出: 123
}
Integer.parseInt(String s)
:将字符串转换为整数。String.valueOf(int i)
:将整数转换为字符串。
5.3 字符串与浮点数的转换
public static void main(String[] args) {
String str = "123.45";
// 将字符串转换为浮点数
double num = Double.parseDouble(str);
System.out.println("num: " + num); // 输出: 123.45
// 将浮点数转换为字符串
String newStr = String.valueOf(num);
System.out.println("newStr: " + newStr); // 输出: 123.45
}
Double.parseDouble(String s)
:将字符串转换为浮点数。String.valueOf(double d)
:将浮点数转换为字符串。
5.4 字符串与布尔值的转换
public static void main(String[] args) {
String str = "true";
// 将字符串转换为布尔值
boolean bool = Boolean.parseBoolean(str);
System.out.println("bool: " + bool); // 输出: true
// 将布尔值转换为字符串
String newStr = String.valueOf(bool);
System.out.println("newStr: " + newStr); // 输出: true
}
Boolean.parseBoolean(String s)
:将字符串转换为布尔值。String.valueOf(boolean b)
:将布尔值转换为字符串。
5.5 字符串与其他类型的转换(如日期等)
import java.text.SimpleDateFormat;
import java.util.Date;
public class StringConversion {
public static void main(String[] args) throws Exception {
// 创建一个字符串,表示日期
String dateStr = "2025-01-12";
// 创建一个SimpleDateFormat对象,用于定义日期格式
// "yyyy-MM-dd" 表示日期的格式是 "年-月-日",例如 2025-01-12
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 使用 parse() 方法将字符串转换为 Date 对象
// parse() 方法会根据 SimpleDateFormat 中定义的格式来解析字符串
Date date = sdf.parse(dateStr);
// 输出转换后的 Date 对象,输出格式会根据默认的日期格式进行显示
// 输出:Sat Jan 12 00:00:00 CST 2025
System.out.println("Date: " + date);
// 使用 format() 方法将 Date 对象转换回字符串
// format() 方法会根据 SimpleDateFormat 中定义的格式,将 Date 转换为符合该格式的字符串
String formattedDate = sdf.format(date);
// 输出转换回的字符串,输出结果将符合 "yyyy-MM-dd" 格式
// 输出:2025-01-12
System.out.println("Formatted Date: " + formattedDate);
}
}
5.6. 基本类型与字符串的转换
public static void main(String[] args) {
int num = 456;
// 基本类型转换为字符串
String str = String.valueOf(num);
System.out.println("str: " + str); // 输出: 456
// 字符串转换为基本类型
int numFromStr = Integer.parseInt(str);
System.out.println("numFromStr: " + numFromStr); // 输出: 456
}
6.字符串拆分
6.1基本用法
split(String regex)
:根据正则表达式将字符串分割成数组。
public static void main(String[] args) {
// 定义一个包含逗号分隔符的字符串
String str = "apple,banana,orange,grape";
// 使用 split() 方法将字符串拆分为数组
String[] fruits = str.split(",");
// 输出拆分后的结果
for (String fruit : fruits) {
System.out.println(fruit);
}
}
输出:
6.2限制分割次数
split(String regex, int limit)
:可以指定拆分的次数(limit
参数)。如果指定了限制,那么返回的数组将最多包含limit
个元素,剩余的部分将合并到最后一个元素中。
public static void main(String[] args) {
// 定义一个包含多个逗号分隔符的字符串
String str = "apple,banana,orange,grape";
// 使用 split() 方法将字符串拆分为最多两个部分
String[] fruits = str.split(",", 2);
// 输出拆分后的结果
for (String fruit : fruits) {
System.out.println(fruit);
}
}
输出:
6.3 使用正则表达式进行拆分
public static void main(String[] args) {
// 定义包含多个空格和逗号的字符串
String str = "apple, banana orange,grape";
// 使用改进后的正则表达式进行拆分
String[] fruits = str.split(",\\s*|\\s+");
// 输出拆分后的结果
for (String fruit : fruits) {
System.out.println(fruit);
}
}
输出:
解释:
1.
,\\s*
,
:这是一个字面量字符,表示逗号,
。它将匹配逗号本身。
\\s*
:匹配零个或多个空白字符。
\\s
匹配任何空白字符,如空格、制表符、换行符等。
*
是量词,表示“匹配零次或多次”。2.
\\s+
\\s
:匹配任何空白字符,包括空格、制表符、换行符等。
+
:量词,表示“匹配一次或多次”,即匹配一个或多个空白字符。
6.4 空字符串的拆分
当字符串中存在连续的分隔符时,
split()
方法将返回包含空字符串的数组元素。
public static void main(String[] args) {
// 定义一个包含连续逗号的字符串
String str = "apple,,banana,,orange";
// 使用 split() 方法拆分字符串
String[] fruits = str.split(",");
// 输出拆分后的结果
for (String fruit : fruits) {
System.out.println("[" + fruit + "]");
}
}
输出:
注意:在连续的分隔符
,,
之间会返回空字符串""
。
7.字符串截取
substring()
方法有两种常见的重载形式:
substring(int beginIndex)
:
- 返回一个从指定位置(
beginIndex
)到字符串结尾的子字符串。beginIndex
是起始位置,索引从0
开始。substring(int beginIndex, int endIndex)
:
- 返回一个从
beginIndex
到endIndex
(不包括endIndex
)的子字符串。beginIndex
是起始位置,endIndex
是结束位置,但不包括endIndex
处的字符。
示例
1. 从指定位置截取到字符串末尾
public static void main(String[] args) {
String str = "Hello, World!";
// 从索引 7 开始截取
String substr = str.substring(7);
System.out.println(substr); // 输出: World!
}
2. 截取指定范围的子字符串
public static void main(String[] args) {
String str = "Hello, World!";
// 截取从索引 0 到 5(不包括索引 5)的子字符串
String substr = str.substring(0, 5);
System.out.println(substr); // 输出: Hello
}
8.其他操作方法
方法 | 功能 |
String trim() | 去掉字符串中的左右空格,保留中间空格 |
String toUpperCase() | 字符串转大写 |
String toLowerCase() | 字符串转小写 |
public static void main(String[] args) {
String str = " HeLLo, WoRLD! ";
// 使用 trim() 去除两端的空白字符
String trimmedStr = str.trim();
System.out.println("Trimmed: '" + trimmedStr + "'"); // 输出: 'HeLLo, WoRLD!'
// 使用 toUpperCase() 将所有字符转换为大写
String upperCaseStr = trimmedStr.toUpperCase();
System.out.println("Uppercase: '" + upperCaseStr + "'"); // 输出: 'HELLO, WORLD!'
// 使用 toLowerCase() 将所有字符转换为小写
String lowerCaseStr = trimmedStr.toLowerCase();
System.out.println("Lowercase: '" + lowerCaseStr + "'"); // 输出: 'hello, world!'
}
输出结果:
二. StringBuilder和StringBuffer
StringBuilder
和StringBuffer
是 Java 中用于操作字符串的两个类,它们的主要功能是提供一个可变的字符序列,与String
不同,String
是不可变的。
方法 | 说明 |
StringBuff append(String str) | 在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、 double、float、int、long、Object、String、StringBuff的变量 |
char charAt(int index) | 获取index位置的字符 |
int length() | 获取字符串的长度 |
int capacity() | 获取底层保存字符串空间总的大小 |
void ensureCapacity(int mininmumCapacity) | 扩容 |
void setCharAt(int index, char ch) | 将index位置的字符设置为ch |
int indexOf(String str) | 返回str第一次出现的位置 |
int indexOf(String str, int fromIndex) | 从fromIndex位置开始查找str第一次出现的位置 |
int lastIndexOf(String str) | 返回最后一次出现str的位置 |
int lastIndexOf(String str, int fromIndex) | 从fromIndex位置开始找str最后一次出现的位置 |
StringBuff insert(int offset, String str) | 在offset位置插入:八种基类类型 & String类型 & Object类型数据 |
StringBuffer deleteCharAt(int index) | 删除index位置字符 |
StringBuffer delete(int start, int end) | 删除[start, end)区间内的字符 |
StringBuffer replace(int start, int end, String str) | 将[start, end)位置的字符替换为str |
String substring(int start) | 从start开始一直到末尾的字符以String的方式返回 |
String substring(int start,int end) | 将[start, end)范围内的字符以String的方式返回 |
StringBuffer reverse() | 反转字符串 |
String toString() | 将所有字符按照String的方式返回 |
public class Main{
public static void main(String[] args) {
// 创建一个 StringBuffer 对象
StringBuffer sb = new StringBuffer("Hello");
// append 方法 - 在末尾追加内容
sb.append(" World");
System.out.println("After append: " + sb);
// charAt 方法 - 获取指定位置的字符
char ch = sb.charAt(6);
System.out.println("Character at index 6: " + ch);
// length 方法 - 获取字符串长度
int length = sb.length();
System.out.println("Length: " + length);
// capacity 方法 - 获取当前容量
int capacity = sb.capacity();
System.out.println("Capacity: " + capacity);
// ensureCapacity 方法 - 确保容量
sb.ensureCapacity(50);
System.out.println("Capacity after ensureCapacity: " + sb.capacity());
// setCharAt 方法 - 设置指定位置的字符
sb.setCharAt(0, 'h');
System.out.println("After setCharAt: " + sb);
// indexOf 方法 - 查找字符串第一次出现的位置
int index = sb.indexOf("World");
System.out.println("Index of 'World': " + index);
// indexOf 方法 - 从指定位置开始查找
index = sb.indexOf("o", 5);
System.out.println("Index of 'o' from index 5: " + index);
// lastIndexOf 方法 - 查找字符串最后一次出现的位置
int lastIndex = sb.lastIndexOf("o");
System.out.println("Last index of 'o': " + lastIndex);
// lastIndexOf 方法 - 从指定位置开始查找最后一次出现的位置
lastIndex = sb.lastIndexOf("o", 7);
System.out.println("Last index of 'o' from index 7: " + lastIndex);
// insert 方法 - 在指定位置插入内容
sb.insert(6, "Java ");
System.out.println("After insert: " + sb);
// deleteCharAt 方法 - 删除指定位置的字符
sb.deleteCharAt(5);
System.out.println("After deleteCharAt: " + sb);
// delete 方法 - 删除指定范围的字符
sb.delete(6, 11);
System.out.println("After delete: " + sb);
// replace 方法 - 替换指定范围内的字符
sb.replace(6, 11, "Universe");
System.out.println("After replace: " + sb);
// substring 方法 - 返回子字符串
String subStr = sb.substring(6);
System.out.println("Substring from index 6: " + subStr);
// substring 方法 - 返回指定范围内的子字符串
subStr = sb.substring(6, 14);
System.out.println("Substring from index 6 to 14: " + subStr);
// reverse 方法 - 反转字符串
sb.reverse();
System.out.println("After reverse: " + sb);
// toString 方法 - 将 StringBuffer 转换为 String
String result = sb.toString();
System.out.println("Final string: " + result);
}
}
1.特点
(1).StringBuilder
和StringBuffer
:它们是可变的。(2).相较于String的性能更好
(3).在字符串拼接替换等场景比String更方便,实用。
2.StringBuilder
和 StringBuffer的区别
线程安全性:
StringBuilder
是非线程安全的,适用于单线程环境。StringBuffer
是线程安全的,适用于多线程环境。性能:
StringBuilder
在单线程环境中性能更高,因为它没有同步的开销。StringBuffer
由于同步机制,在多线程环境中提供线程安全,但性能会略低。使用场景:
- 在单线程环境下,使用
StringBuilder
更为合适,因其性能更优。- 在多线程环境下,使用
StringBuffer
更为合适,因其线程安全。
原文地址:https://blog.csdn.net/2202_75357702/article/details/145092822
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!