java-String相关基础函数

3 阅读11分钟

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, StringBuffer
  • char, char[]
  • int, long, float, double
  • boolean
  • Object (调用其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复制字符到数组

最佳实践

  1. 预分配容量:如果知道大概长度,预分配容量避免扩容
  2. 循环中必用StringBuilder:避免在循环中使用"+"拼接字符串
  3. 优先使用StringBuilder:除非需要线程安全,否则不用StringBuffer
  4. 适时调用trimToSize():如果内存紧张,可以调用trimToSize()释放多余空间
  5. 避免频繁toString():在循环中避免频繁调用toString(),最后调用一次即可
  6. 使用合适的初始值:如果有初始字符串,使用带String参数的构造器