一 java中常用方法
1. 基础获取类
s 表示某一个字符串string
| 方法 | 说明 | 竞赛避坑指南 |
|---|---|---|
s.length() | 返回字符串长度 | 注意:它是方法,必须带 ()。数组是 .length(属性)。 |
s.charat(i) | 获取索引 i 处的字符 | 配合 while 循环做边界检查(i >= 0 && i < s.length())。 |
s.indexof(str) | 查找子串第一次出现的位置 | 如果没找到,返回 -1。在处理特定模式搜索时极好用。 |
s.substring(start, end) | 截取子串 | 重点:左闭右开 [start, end)。包含 start,但不包含 end。 |
2. 比较与判断类
在竞赛中,千万不要用 == 比较字符串内容!
• s.equals(s2):比较两个字符串内容是否完全相等。
• s.equalsignorecase(s2):忽略大小写比较(在某些天梯赛题目中很有用)。
• s.startswith(prefix) / s.endswith(suffix):判断是否以某段开头或结尾。
• s.isempty():判断长度是否为 0。
3. 修改与转换类(产生新字符串)
注意:java 中的 string 是不可变的,这些方法都会返回一个全新的字符串。
• s.tolowercase() / s.touppercase():全部转小写/大写。
• s.trim():去掉首尾空格(处理输入数据不规范时是救命药)。
• s.replace(old, new):替换所有匹配的字符或子串。
• s.tochararray():竞赛神技。如果你觉得 s.charat(i) 写起来太长,先转成 char[],然后用 arr[i] 访问,速度更快且代码更短。
4. 分割与合并
s.split(string regex):按规则切分。
例: string[] words = s.split(" "); 可以把句子拆成单词。
string.join(delimiter, elements):把数组或列表用指定符号连起来。
5.stringbuilder
如果在循环里频繁修改字符串(比如 s += “a”),java 每次都会创建新对象,导致 超时,所以我们可以选择来new上一个stringbuilder
为什么我们要使用stringbuilder呢?因为在java中,string是不可变的,比如当我们有一个字符串 s = “a” 时,执行"s = s + "b"时:
1.java不会在原来的"a"的后面直接加"b";
2.而是创建一个新对象,把"a"拷贝过去,再把"b"加上去;
3.导致原来的"a"变成了多余的那个,占用了内存
所以当我们在循环10000做" s += “a” " ,则会创建10000个临时字符串对象,直接让内存爆炸💥,同时时间复杂度也到达了o(n ^ 2).
而stringbuilder的优势是他内部有着一个字符数组(char[]),当我们执行sb.append时,它直接在数组的下一个空位填入‘b',不创建新对象,如果数组满了,它会自动扩大一倍(扩容),然后继续填,时间复杂度接近 o(n).
竞赛常用方法:
| 方法 | 说明 | 竞赛场景 |
|---|---|---|
sb.append(xxx) | 追加内容 | 拼接答案、拼接数字、拼接字符。支持链式调用。 |
sb.reverse() | 原地翻转 | 判断回文、大数加法(低位对齐)、反转字符串。 |
sb.delete(start, end) | 删除一段 | 类似于 substring 的逆操作,清理不需要的后缀。 |
sb.setcharat(i, c) | 修改指定字符 | 这是 string 做不到的!修改某个位置的字符。 |
sb.insert(offset, str) | 在指定位置插入 | 比如在最前面插入一个负号。 |
sb.length() | 获取当前长度 | 循环遍历时用。 |
sb.tostring() | 转回 string | 最终输出答案时必须调用。 |
sb.setlength(0) | 清空 stringbuilder | 把指针重置为 0,内容逻辑上清空了 |
现在有一个新场景,假设我们要处理 n n n 组数据,每组数据都要拼一个结果并输出。
a方法:
stringbuilder sb = new stringbuilder();
for (int i = 0; i < 3; i++) {
sb.append("data" + i);
system.out.println(sb.tostring());
}
这种情况下
第一轮:data0
第二轮:data0data1 <-- 错了!上一轮的脏数据还在!
第三轮:data0data1data2
数据乱了,并不是我们想要的结果
b方法:直接new
for (int i = 0; i < 100000; i++) {
stringbuilder sb = new stringbuilder();
sb.append("data" + i);
system.out.println(sb.tostring());
// 循环结束,sb 变成垃圾
}
这种情况下,成功输出我们想要的结果
后果:
内存直接爆炸,你在内存里创建了 10 万个对象,又丢弃了 10 万个,同时每次 new 出来的数组都很小,每次都要重新经历从小变大的扩容过程。
c方法:使用setlength(0)
stringbuilder sb = new stringbuilder();
for (int i = 0; i < 100000; i++) {
sb.setlength(0);
sb.append("data" + i);
system.out.println(sb.tostring());
}
这种情况下,成功输出我们想要的结果
后果:
全程只有 1 个对象,同时 比如第一轮你的字符串很长,把数组撑到了 5000 大小。第二轮开始时,sb 依然拥有 5000 的容量,根本不需要再扩容,直接填进去就行
二 . 四种字符串必会技能
1.字符串与数字的切换
场景:题目给了“1000”,要求变成数字1000去做加减乘除,或者是算出结果250后将其拼接到字符串
a.string 转 int / long
integer.parseint(s);
string s = "12345";
int num = integer.parseint(s); // 转 int
long bignum = long.parselong("9999999999"); // 转 long (超过21亿必须用这个)
int 最大只能存约 21 亿 ( 2 × 10 9 2 \times 10^9 2×109)。
如果题目说数字可能很大(比如 18 位),必须用 long.parselong。
如果字符串里混进了空格或字母(比如 " 123" 或 “12a”),这行代码会直接报错
numberformatexception。
如果只是首尾空格,直接用s.trim()就好
但如果是“123ad 23;”等这些混入了各种非数字的字符时,则需要使用其他方法
第一种方法:暴力清洗,直接把所有非数字的去掉
string s = "123ad 23;";
string clean = s.replaceall("[^0-9]", "");
// [^0-9] == \\d
意思是:除了 0-9 以外的所有字符,把所有非数字字符替换成空字符串
int num = integer.parseint(clean);
system.out.println(num);
//结果为:12323
如果要求读取直到遇到非数字就输出,那么就不能使用上面的方法
第二种方法:精细提取法(读取直到遇到非数字)
string s = "123ad 23;";
int num = 0;
for (int i = 0; i < s.length(); i++) {
char ch = s.charat(i);
// 如果是数字,就累加
if (character.isdigit(ch)) {
// 核心公式:原数字 * 10 + 新的一位
// c - '0' 是把字符变成数字
num = num * 10 + (ch - '0');
} else {
break;
}
}
system.out.println(num);
//结果为:123
b. int/long 转 string
这是为了输出或者拼接
int num = 42; // 写法 1 :利用 java 的自动装箱,虽然不是最快但最不容易错 string s1 = num + ""; // 写法 2 :性能稍好,看着专业 string s2 = string.valueof(num);
2.字符与ascii 码
场景: “把所有字母向后移 3 位”,或者“判断这个字符是不是数字”
核心原理: char 在 java 里本质上是一个整数,要把 char 当成整数去用
‘0’ 的整数值是 48。
‘a’ 的整数值是 65。
‘a’ 的整数值是 97。
a.字符转数字
问题:怎么把字符 ‘5’ 变成整数 5?
int num = (int)'5'; //错误 //输出:53 并非 5
int num = '5' - '0'; //正确 // 53 - 48 = 5
b. 字母移位
char c = 'a'; // 往后移 1 位变成 'b' char next = (char)(c + 1); // 必须强转回 char,因为计算结果是 int
c.字符的大小写转换
//'a' = 65, 'a' = 97
//小写变大写 减32
char uppercaseletters = (char)('a' - 32);
//大写变小写 加32
char lowercaseletters = (char)('b' + 32);
d. 判断字符类型
用 java 自带的工具类 character
character.isdigit( c ) : 是不是 ‘0’-‘9’?
character.isletter( c ): 是不是字符?
character.isletterordigit( c ): 是不是字符或者数字?
character.isuppercase( c ): 是不是大写?
character.islowercase( c ): 是不是小写?
3.格式化输出
题目出现要“保留小数”和“补零”的情况下:
double pi = 3.1415926;
int hour = 5;
// 1. 保留 2 位小数 (会自动四舍五入)
system.out.printf("%.2f", pi);
// 输出: 3.14
// 2. 整数补零 (总共占 2 位,不够补 0)
system.out.printf("%02d", hour);
// 输出: 05
// 3. 组合拳:输出 "time: 05, score: 3.14"
string res = string.format("time: %02d, score: %.2f", hour, pi);
system.out.println(res);
4. 字典序比较 (排序用的)
题目出现要“请把这些名字按字典序从小到大排列”, 不能用 < 或 > 比较字符串,要用 compareto()
string s1 = "apple";
string s2 = "banana";
// 返回值规则:
// < 0 : s1 在 s2 前面 (apple < banana)
// == 0 : 相等
// > 0 : s1 在 s2 后面
int result = s1.compareto(s2);
// 对字符串数组排序
string[] arr = {"dog", "cat", "apple"};
arrays.sort(arr); // 默认就是按字典序排的:apple, cat, dog
5. 正则表达式分割
题目给出:“please, split this… sentence!” (标点混杂空格),用普通的 split(" ") 切不干净,所以给用下面的方法
string s = "hello, world! java";
// split 里面填的是正则表达式
// [ ,!]+ 表示:只要遇到 空格、逗号、感叹号 中的任意一个或多个,就切一刀
string[] parts = s.split("[ ,!]+");
总结
到此这篇关于java字符串操作的四种正确姿势与常用模板的文章就介绍到这了,更多相关java字符串操作内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论