chatAt()函数
charAt() 是字符串方法,用于获取字符串中指定位置的字符。
- 与数组索引的区别,
charAt()对越界索引返回空字符串,而数组索引方式返回undefined charAt()不传参数时默认返回第一个字符
Character.getNumericValue()函数
Character.getNumericValue() 是 Java 中 Character 类的一个静态方法,用于获取字符的数值(如果该字符表示一个数字)。
- 支持阿拉伯数字转换,同时支持其他数字系统,如罗马数字,全角数字,中文数字
- 对于非数字字符,返回-1
- 可以进行16进制字符转换,不区分大小写
- 返回值范围:
- 有效的数字:0-35(0-9, A-Z, a-z 在16进制中)
- 特殊数字字符:如罗马数字
- -1:不是数字字符
- -2:字符是数字但无法确定具体值
与 char - '0' 方法相比,传统方法(仅适用于阿拉伯数字):
char c = '5';
int value = c - '0'; // 5
与 Character.digit() 的区别:
// 两者功能类似,但 getNumericValue() 支持更多数字系统
System.out.println(Character.getNumericValue('三')); // 3
System.out.println(Character.digit('三', 10)); // -1
peek()函数
combinations.peek() 是 Java 中 Queue 或 Deque 接口的方法(尤其是当 combinations 是一个队列时),它用于查看队列头部的元素但不移除它。
和其他方法的对比
| 方法 | 作用 | 队列为空时的行为 |
|---|---|---|
peek() | 查看队首元素(不移除) | 返回 null |
element() | 查看队首元素(不移除) | 抛出 NoSuchElementException |
poll() | 获取并移除队首元素 | 返回 null |
remove() | 获取并移除队首元素 | 抛出 NoSuchElementException |
StringBuilder 类方法总结
一、构造方法
| 方法 | 说明 |
|---|---|
StringBuilder() | 创建初始容量为16的空StringBuilder |
StringBuilder(int capacity) | 创建指定初始容量的空StringBuilder |
StringBuilder(String str) | 创建包含指定字符串的StringBuilder |
StringBuilder(CharSequence seq) | 创建包含指定字符序列的StringBuilder |
二、主要修改方法
1. append()
append()方法:将指定的字符串或字符追加到此序列的末尾。
支持的参数类型:
String,StringBuilder,StringBufferchar,char[]int,long,float,doublebooleanObject(调用其toString()方法)
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // "Hello World"
sb.append(123); // "Hello World123"
sb.append(true); // "Hello World123true"
sb.append(new Object()); // 追加对象的字符串表示
// 支持各种数据类型
sb.append('!'); // 字符
sb.append(3.14); // 浮点数
sb.append(new char[]{'a','b'}); // 字符数组
// 链式调用
sb.append(" More").append(" Text").append(123);
2. insert()
insert()方法:在指定的偏移量位置插入值。
支持的参数类型:与append()相同
StringBuilder sb = new StringBuilder("Hello");
sb.insert(0, "Say: "); // "Say: Hello" (在索引0处插入)
sb.insert(5, " World"); // "Say: Hello World" (在索引5处插入)
sb.insert(sb.length(), "!"); // 在末尾插入
// 插入各种数据类型
sb.insert(3, 123); // "Say123: Hello World!"
sb.insert(4, true); // "Say123true: Hello World!"
// 插入数组的一部分
char[] chars = {'x', 'y', 'z'};
sb.insert(0, chars, 1, 2); // 在位置0插入chars数组从索引1开始的2个字符
3. delete()
delete()方法:
deleteCharAt(int index):删除某个索引位置上的字符,index不能越界delete(int start, int end):删除从start(包含)到end(不包含)位置的字符,start为0~length-1,end可以超出长度
StringBuilder sb = new StringBuilder("Hello World");
// deleteCharAt() - 删除指定位置的单个字符
sb.deleteCharAt(5); // "HelloWorld" (删除空格)
sb.deleteCharAt(0); // "elloWorld" (删除第一个字符)
// delete() - 删除指定范围的字符
sb.delete(2, 5); // "elWorld" (删除索引2-4的字符)
sb.delete(0, sb.length()); // "" (清空所有内容)
// end索引可以超出长度,会删除到末尾
sb.append("Hello World");
sb.delete(6, 100); // "Hello " (end超出长度,删除到末尾)
4. replace()
replace方法:
replace(int start, int end, String str):从start到end之间的字符串替换成新字符串setCharAt(int index, char ch):替换指定位置的单个字符
StringBuilder sb = new StringBuilder("Hello World");
// replace() - 替换子串
sb.replace(6, 11, "Java"); // "Hello Java" (替换索引6-10)
sb.replace(0, 5, "Hi"); // "Hi Java" (替换索引0-4)
sb.replace(3, 3, " there"); // "Hi there Java" (在索引3处插入)
// setCharAt() - 替换单个字符
sb.setCharAt(0, 'h'); // "hi there Java" (替换第一个字符)
sb.setCharAt(1, 'i'); // "hi there Java" (第二个字符不变,此处'i'本来就是'i')
5. reverse()
reverse()方法:倒置字符串顺序
StringBuilder sb = new StringBuilder("Hello");
sb.reverse(); // "olleH"
// 可用于判断回文
StringBuilder palindrome = new StringBuilder("racecar");
System.out.println(palindrome.toString().equals(palindrome.reverse().toString())); // true
// 反转后仍可继续操作
sb.reverse().append(" World"); // "Hello World"
6. substring()
substring()方法:截取子串(返回String,不影响原StringBuilder)
substring(int start):从start(包含)位置截取到末尾substring(int start, int end):从start(包含)到end(不包含)位置截取
StringBuilder sb = new StringBuilder("Hello World");
// 截取从指定位置到末尾
String sub1 = sb.substring(6); // "World" (原sb不变)
System.out.println(sb); // "Hello World"
// 截取指定范围的子串
String sub2 = sb.substring(0, 5); // "Hello" (原sb不变)
System.out.println(sb); // "Hello World"
// 注意:substring()返回String,不是StringBuilder
String sub3 = sb.substring(2, 7); // "llo W"
// 如果start=end,返回空字符串
String empty = sb.substring(3, 3); // ""
三、查询和容量方法
7. length()
length()方法:返回StringBuilder对象当前包含的字符数(长度)
StringBuilder sb = new StringBuilder("Hello");
int len = sb.length(); // 5
sb.append(" World");
len = sb.length(); // 11
sb.delete(5, 11);
len = sb.length(); // 5
// 长度与容量的区别
System.out.println("长度: " + sb.length()); // 5
System.out.println("容量: " + sb.capacity()); // 21 (默认16 + 初始字符串长度5)
8. capacity()
capacity()方法:返回StringBuilder对象的当前容量(可存储的字符数)
StringBuilder sb1 = new StringBuilder(); // 默认容量16
System.out.println(sb1.capacity()); // 16
StringBuilder sb2 = new StringBuilder(50); // 指定容量50
System.out.println(sb2.capacity()); // 50
StringBuilder sb3 = new StringBuilder("Hello World"); // 容量为16+11=27
System.out.println(sb3.capacity()); // 27
// 容量会自动增长
StringBuilder sb4 = new StringBuilder();
for (int i = 0; i < 100; i++) {
sb4.append(i);
}
System.out.println("长度: " + sb4.length()); // 大约189(取决于数字位数)
System.out.println("容量: " + sb4.capacity()); // 大于等于189,通常是原来的两倍
9. charAt()
charAt()方法:返回指定索引处的字符
StringBuilder sb = new StringBuilder("Hello World");
char ch1 = sb.charAt(0); // 'H' (第一个字符)
char ch2 = sb.charAt(6); // 'W' (第七个字符)
char ch3 = sb.charAt(sb.length() - 1); // 'd' (最后一个字符)
// 遍历所有字符
for (int i = 0; i < sb.length(); i++) {
System.out.print(sb.charAt(i) + " ");
}
// 输出: H e l l o W o r l d
// 索引越界会抛出异常
try {
char ch4 = sb.charAt(100); // StringIndexOutOfBoundsException
} catch (StringIndexOutOfBoundsException e) {
System.out.println("索引越界!");
}
10. indexOf()
indexOf()方法:查找子串在StringBuilder中第一次出现的位置
indexOf(String str):从头开始查找indexOf(String str, int fromIndex):从指定位置开始查找
StringBuilder sb = new StringBuilder("Hello World Hello");
int index1 = sb.indexOf("Hello"); // 0 (第一次出现的位置)
int index2 = sb.indexOf("World"); // 6
int index3 = sb.indexOf("Java"); // -1 (未找到)
// 从指定位置开始查找
int index4 = sb.indexOf("Hello", 1); // 12 (从索引1开始查找)
int index5 = sb.indexOf("o"); // 4 (字符'o'第一次出现)
int index6 = sb.indexOf("o", 5); // 7 (从索引5开始查找'o')
// 查找空字符串
int index7 = sb.indexOf(""); // 0 (空字符串在开头)
int index8 = sb.indexOf("", 5); // 5 (从索引5开始的空字符串)
11. lastIndexOf()
lastIndexOf()方法:查找子串在StringBuilder中最后一次出现的位置
lastIndexOf(String str):从末尾向前查找lastIndexOf(String str, int fromIndex):从指定位置向前查找
StringBuilder sb = new StringBuilder("Hello World Hello");
int lastIndex1 = sb.lastIndexOf("Hello"); // 12 (最后一次出现的位置)
int lastIndex2 = sb.lastIndexOf("World"); // 6
int lastIndex3 = sb.lastIndexOf("Java"); // -1 (未找到)
// 从指定位置向前查找
int lastIndex4 = sb.lastIndexOf("Hello", 10); // 0 (从索引10向前查找)
int lastIndex5 = sb.lastIndexOf("o"); // 15 (字符'o'最后一次出现)
int lastIndex6 = sb.lastIndexOf("o", 10); // 7 (从索引10向前查找'o')
// 查找空字符串
int lastIndex7 = sb.lastIndexOf(""); // 17 (空字符串在末尾)
int lastIndex8 = sb.lastIndexOf("", 5); // 5 (到索引5为止的空字符串)
12. subSequence()
subSequence()方法:返回一个新的字符序列,包含此序列中指定位置的字符子序列
StringBuilder sb = new StringBuilder("Hello World");
// 获取子序列
CharSequence seq1 = sb.subSequence(0, 5); // "Hello"
CharSequence seq2 = sb.subSequence(6, 11); // "World"
// 子序列是只读的
System.out.println(seq1.length()); // 5
System.out.println(seq1.charAt(0)); // 'H'
// 与substring()的区别:返回类型不同
String str = sb.substring(0, 5); // 返回String
CharSequence seq = sb.subSequence(0, 5); // 返回CharSequence
// 可以传递给接受CharSequence参数的方法
printSequence(sb.subSequence(3, 8)); // 传递CharSequence
// 常用实现CharSequence的类:String, StringBuilder, StringBuffer, CharBuffer
13. ensureCapacity()
ensureCapacity()方法:确保容量至少等于指定的最小值
StringBuilder sb = new StringBuilder();
// 默认容量
System.out.println(sb.capacity()); // 16
// 确保最小容量
sb.ensureCapacity(50);
System.out.println(sb.capacity()); // 50 (可能更大)
sb.ensureCapacity(100);
System.out.println(sb.capacity()); // 100 (可能更大,如102)
// 如果当前容量大于指定值,则不变
sb.ensureCapacity(50);
System.out.println(sb.capacity()); // 100 (不变,因为100>50)
// 实际应用:预分配足够空间避免扩容
StringBuilder largeBuilder = new StringBuilder();
largeBuilder.ensureCapacity(10000); // 预分配大容量
for (int i = 0; i < 10000; i++) {
largeBuilder.append("x"); // 避免频繁扩容
}
14. trimToSize()
trimToSize()方法:尝试减少字符序列的存储空间,将容量缩减到实际长度
StringBuilder sb = new StringBuilder(100); // 初始容量100
sb.append("Hello"); // 实际只用5个字符
System.out.println("长度: " + sb.length()); // 5
System.out.println("容量: " + sb.capacity()); // 100 (浪费95个字符空间)
// 缩减容量到实际大小
sb.trimToSize();
System.out.println("缩减后容量: " + sb.capacity()); // 5
// 注意:trimToSize()可能增加后续操作的开销
sb.append(" World");
System.out.println("追加后容量: " + sb.capacity()); // 可能需要扩容
// 适用场景:内存紧张且不再修改时
StringBuilder finalBuilder = new StringBuilder(1000);
// ... 填充数据 ...
finalBuilder.trimToSize(); // 释放多余空间
String result = finalBuilder.toString(); // 转换为String后使用
15. setLength()
setLength()方法:设置字符序列的长度
StringBuilder sb = new StringBuilder("Hello World");
// 设置更小的长度(截断)
sb.setLength(5);
System.out.println(sb); // "Hello"
System.out.println(sb.length()); // 5
// 设置更大的长度(用null字符填充)
sb.setLength(10);
System.out.println(sb); // "Hello\0\0\0\0\0"
System.out.println(sb.length()); // 10
// 查看填充的null字符
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) == '\0') {
System.out.print("\\0 ");
} else {
System.out.print(sb.charAt(i) + " ");
}
}
// 输出: H e l l o \0 \0 \0 \0 \0
// 清空StringBuilder
sb.setLength(0);
System.out.println("清空后长度: " + sb.length()); // 0
System.out.println("是否为空: " + (sb.length() == 0)); // true
16. setCharAt()
setCharAt()方法:将给定索引处的字符设置为指定的字符
StringBuilder sb = new StringBuilder("Hello");
// 替换单个字符
sb.setCharAt(1, 'a'); // "Hallo"
sb.setCharAt(0, 'J'); // "Jallo"
sb.setCharAt(4, 'y'); // "Jally"
// 索引必须在有效范围内
try {
sb.setCharAt(10, 'x'); // StringIndexOutOfBoundsException
} catch (StringIndexOutOfBoundsException e) {
System.out.println("索引越界!");
}
// 与replace()方法的区别:setCharAt()只替换一个字符
sb.setCharAt(1, 'e'); // "Jelly" (替换单个字符)
sb.replace(1, 2, "a"); // "Jally" (替换子串,效果相同但参数类型不同)
// 实际应用:简单加密(字符替换)
StringBuilder message = new StringBuilder("secret");
for (int i = 0; i < message.length(); i++) {
char original = message.charAt(i);
char encrypted = (char)(original + 1); // 每个字符ASCII值加1
message.setCharAt(i, encrypted);
}
System.out.println(message); // "tfdsfu"
17.corePointAt()
codePointAt(int index) 方法返回指定索引处的字符(Unicode 代码点)。代码点(Code Point) 是 Unicode 字符的数值表示,范围是 0x0000 到 0x10FFFF。
四、与String互转
18. toString()
toString()方法:将StringBuilder对象转换为String对象
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World").append("!");
// 转换为String
String str = sb.toString();
System.out.println(str); // "Hello World!"
System.out.println(str.getClass().getName()); // java.lang.String
// 转换后对StringBuilder的修改不影响已转换的String
sb.append(" More");
System.out.println(sb); // "Hello World! More"
System.out.println(str); // "Hello World!" (不变)
// 性能提示:避免在循环中频繁调用toString()
StringBuilder numbers = new StringBuilder();
for (int i = 0; i < 1000; i++) {
numbers.append(i);
// 错误:每次循环都创建新String
// String temp = numbers.toString();
}
// 正确:最后调用一次toString()
String result = numbers.toString();
// toString()方法的重写
class MyStringBuilder {
private StringBuilder sb = new StringBuilder();
@Override
public String toString() {
return sb.toString();
}
}
19. String构造器转换
String构造器转换:通过String类的构造器将StringBuilder转换为String
StringBuilder sb = new StringBuilder("Hello World");
// 方法1:使用String构造器
String str1 = new String(sb);
System.out.println(str1); // "Hello World"
// 方法2:使用String构造器指定字符序列
CharSequence cs = sb;
String str2 = new String(cs);
System.out.println(str2); // "Hello World"
// 方法3:转换为字符数组再创建String
char[] chars = new char[sb.length()];
sb.getChars(0, sb.length(), chars, 0);
String str3 = new String(chars);
System.out.println(str3); // "Hello World"
// 与toString()的区别
// 1. toString()可能被重写,而String构造器总是创建新String
// 2. String构造器可以接受任何CharSequence
// 3. 性能上toString()通常更高效
19. String转StringBuilder
String转StringBuilder:将String对象转换为StringBuilder对象
String str = "Hello World";
// 方法1:使用StringBuilder构造器
StringBuilder sb1 = new StringBuilder(str);
System.out.println(sb1); // "Hello World"
// 方法2:创建空StringBuilder后append
StringBuilder sb2 = new StringBuilder();
sb2.append(str);
System.out.println(sb2); // "Hello World"
// 方法3:使用链式调用
StringBuilder sb3 = new StringBuilder().append(str).append("!");
System.out.println(sb3); // "Hello World!"
// 方法4:从String创建并指定容量
StringBuilder sb4 = new StringBuilder(str.length() + 10); // 预分配额外空间
sb4.append(str);
// 实际应用:处理多个String
String[] words = {"Hello", " ", "World", "!"};
StringBuilder sentence = new StringBuilder();
for (String word : words) {
sentence.append(word);
}
System.out.println(sentence); // "Hello World!"
// 注意:String是不可变的,StringBuilder是可变的
str.toUpperCase(); // 返回新String,原str不变
sb1.reverse(); // 直接修改sb1
System.out.println(str); // "Hello World" (不变)
System.out.println(sb1); // "dlroW olleH" (已修改)
五、链式调用
// 支持方法链式调用
String result = new StringBuilder()
.append("Hello")
.append(" ")
.append("World")
.append("!")
.insert(5, ",") // "Hello, World!"
.replace(5, 6, " ") // "Hello World!"
.reverse() // "!dlroW olleH"
.toString(); // 最后转换为String
// 注意:链式调用时,每个方法都返回同一个StringBuilder实例
StringBuilder sb = new StringBuilder();
sb.append("A").append("B").append("C");
System.out.println(sb); // "ABC"
常用方法速查表
| 方法 | 返回类型 | 描述 |
|---|---|---|
append(xxx) | StringBuilder | 追加内容 |
insert(int, xxx) | StringBuilder | 在指定位置插入 |
delete(int, int) | StringBuilder | 删除子串 |
deleteCharAt(int) | StringBuilder | 删除单个字符 |
replace(int, int, String) | StringBuilder | 替换子串 |
reverse() | StringBuilder | 反转字符串 |
length() | int | 获取长度 |
capacity() | int | 获取容量 |
charAt(int) | char | 获取指定位置字符 |
indexOf(String) | int | 查找子串 |
lastIndexOf(String) | int | 从后查找子串 |
substring(int) | String | 获取子串 |
substring(int, int) | String | 获取子串 |
subSequence(int, int) | CharSequence | 获取子序列 |
toString() | String | 转换为String |
setLength(int) | void | 设置长度 |
ensureCapacity(int) | void | 确保最小容量 |
trimToSize() | void | 缩减容量到实际大小 |
setCharAt(int, char) | void | 设置指定位置字符 |
codePointAt(int) | int | 获取代码点 |
getChars(int, int, char[], int) | void | 复制字符到数组 |
最佳实践
- 预分配容量:如果知道大概长度,预分配容量避免扩容
- 循环中必用StringBuilder:避免在循环中使用"+"拼接字符串
- 优先使用StringBuilder:除非需要线程安全,否则不用StringBuffer
- 适时调用trimToSize():如果内存紧张,可以调用trimToSize()释放多余空间
- 避免频繁toString():在循环中避免频繁调用toString(),最后调用一次即可
- 使用合适的初始值:如果有初始字符串,使用带String参数的构造器