文章目录
- 前言
- 一、字符串比较
- 1.1 比较用equals(),不能用==
- 1.2 忽略大小写比较用equalsIgnoreCase()
- 二、搜索子串contains()、indexOf()、lastIndexOf()、startsWith()、endsWith()
- 三、提取子串substring()
- 四、去除首尾空白字符trim()、stripLeading()、stripTrailing()、strip()
- 五.判断字符串是否为空isEmpty()和空白字符串isBlank()
- 六.替换子串replace(),或正则表达式
- 6.1 replace()
- 6.2 使用正则表达式:
- 七 分割字符串split()、拼接字符串join()
- 八 转换为char[]
- 九 高效字符串拼接StringBuilder、StringJoiner和join()
- 9.1 StringBuilder
- 9.2 StringJoiner
- 9.3 不需要指定“开头”和“结尾”时用join()
- 总结
前言
在编程中经常需要对字符串进行处理,下面介绍了一些对字符串比较常用的处理方法。
一、字符串比较
1.1 比较用equals(),不能用==
public class TestString {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true
}
}
这里会发现用== 和用 equals() 都是true,只是Java编译器在编译期,会自动把所有相同的字符串当作一个对象放入常量池,自然s1和s2的引用就是相同的。
换一种写法 == 就会出现false:
public class TestString {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO".toLowerCase();
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2)); //true
}
}
1.2 忽略大小写比较用equalsIgnoreCase()
public class TestString {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO".toLowerCase();
System.out.println(s1.equals(s2)); //false
System.out.println(s1.equalsIgnoreCase(s2)); //true
}
}
二、搜索子串contains()、indexOf()、lastIndexOf()、startsWith()、endsWith()
public class TestString {
public static void main(String[] args) {
"sunshine".contains("sun"); // true
"sunshine".indexOf("s"); // 0
"sunshine".lastIndexOf("s"); // 3
"sunshine".startsWith("sun"); // true
"sunshine".endsWith("ine"); // true
}
}
三、提取子串substring()
语法:
//beginIndex -- 起始索引(包括), 索引从 0 开始。
public String substring(int beginIndex)
//endIndex -- 结束索引(不包括)。
public String substring(int beginIndex, int endIndex)
public class TestString {
public static void main(String[] args) {
"sunshine".substring(1); // "unshine"
"sunshine".substring(3, 7); //"shine"
}
}
四、去除首尾空白字符trim()、stripLeading()、stripTrailing()、strip()
使用trim()方法可以移除字符串首尾空白字符。空白字符包括空格,\t,\r,\n:
public class TestString {
public static void main(String[] args) {
" \tsunshine\r\n ".trim(); // "sunshine"
"\u3000sunshine\u3000".strip(); // "sunshine"
" sunshine ".stripLeading(); // "sunshine "
" sunshine ".stripTrailing(); // " sunshine"
}
}
五.判断字符串是否为空isEmpty()和空白字符串isBlank()
代码如下(示例):
public class TestString {
public static void main(String[] args) {
"".isEmpty(); // true,因为字符串长度为0
" ".isEmpty(); // false,因为字符串长度不为0
" \n".isBlank(); // true,因为只包含空白字符
" Hello ".isBlank(); // false,因为包含非空白字符
}
}
六.替换子串replace(),或正则表达式
6.1 replace()
public class TestString {
public static void main(String[] args) {
String s = "sunsunshine";
s.replace('s', 'w'); // "wunwunwhine",所有字符's'被替换为'w'
s.replace("su", "~~"); // "~~n~~nshine",所有子串"su"被替换为"~~"
}
}
6.2 使用正则表达式:
public class TestString {
public static void main(String[] args) {
String s = "A,,B;C ,D";
s.replaceAll("[\\,\\;\\s]+", ","); // "A,B,C,D"
}
}
七 分割字符串split()、拼接字符串join()
public class TestString {
public static void main(String[] args) {
String s = "A,B,C,D";
//分割字符串
String[] ss = s.split("\\,"); // {"A", "B", "C", "D"}
String[] arr = {"A", "B", "C"};
//拼接字符串
String s = String.join("***", arr); // "A***B***C"
}
}
八 转换为char[]
String和char[]类型可以互相转换:
public class TestString {
public static void main(String[] args) {
char[] cs = "Hello".toCharArray(); // String -> char[]
String s = new String(cs); // char[] -> String
}
}
如果修改了char[]数组,String不会改变
public class TestString {
public static void main(String[] args) {
char[] cs = "Hello".toCharArray(); // String -> char[]
String s = new String(cs); // char[] -> String
System.out.println(s);//"Hello"
cs[0] = 'X';
System.out.println(s);//"Hello"
}
}
这是因为通过new String(char[])创建新的String实例时,它并不会直接引用传入的char[]数组,而是会复制一份,所以,修改外部的char[]数组不会影响String实例内部的char[]数组,因为这是两个不同的数组。
九 高效字符串拼接StringBuilder、StringJoiner和join()
9.1 StringBuilder
Java编译器对String做了特殊处理,使得我们可以直接用+拼接字符串。
public class TestString {
public static void main(String[] args) {
String s = "";
for (int i = 0; i < 1000; i++) {
s = s + "," + i;
}
}
}
但是不建议这样使用,因为,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样会产生很多临时对象,不但浪费内存,还影响GC效率。
为了能高效拼接字符串,建议使用StringBuilder,它是一个可变对象,可以预分配缓冲区,这样新增字符时不会创建新的临时对象。
StringBuilder还可以使用链式操作,这是因为append()方法会返回this,这样,就可以不断调用自身的其他方法。
public class TestString {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 100; i++) {
sb.append(',');
sb.append(i);
}
String s = sb.toString();
//使用链式操作
StringBuilder sb1 = new StringBuilder(1024);
sb1.append("Mr ")
.append("Zhang")
.append("!")
.insert(0, "Hello, ");
//"Hello, Mr Zhang!"
System.out.println(sb.toString());
}
}
9.2 StringJoiner
在实际开发中,我们经常需要对多条数据进行拼接然后返回,这就是要用分隔符拼接数组,这时候如果用StringJoiner就比较方便了。
我们先来看看用StringBuilder要怎么处理:
public class TestString {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(1024);
String[] msgs= {"第1条处理成功", "第2条处理成功", "第3条处理失败"};
sb.append("处理情况:");
for (String msg: msgs) {
sb.append(msg).append(",");
}
// 注意去掉最后的",":
sb.delete(sb.length() - 1, sb.length());
sb.append("!");
//处理情况:第1条处理成功,第2条处理成功,第3条处理失败!
System.out.println(sb.toString());
}
}
下面来看看用StringJoiner要怎么处理:
public class TestString {
public static void main(String[] args) {
StringJoiner sj = new StringJoiner(",");
String[] msgs= {"第1条处理成功", "第2条处理成功", "第3条处理失败"};
for (String msg: msgs) {
sj.add(msg);
}
//第1条处理成功,第2条处理成功,第3条处理失败
System.out.println(sj.toString());
//还可以添加头和尾
StringJoiner sjoiner = new StringJoiner(",","处理情况:","!");
for (String msg: msgs) {
sjoiner.add(msg);
}
//处理情况:第1条处理成功,第2条处理成功,第3条处理失败!
System.out.println(sjoiner.toString());
}
}
这样拼接字符串就很方便了。
9.3 不需要指定“开头”和“结尾”时用join()
除此之外,String还提供了一个静态方法join(),这个在上面拼接字符串的时候已经提过了,这个方法适合用在不需要指定“开头”和“结尾”的时候。
public class TestString {
public static void main(String[] args) {
String[] arr = {"A", "B", "C"};
//拼接字符串
String s = String.join("***", arr); // "A***B***C"
String[] msgs= {"第1条处理成功", "第2条处理成功", "第3条处理失败"};
//第1条处理成功,第2条处理成功,第3条处理失败
String msg = String.join(",", msgs);
}
}
总结
本文介绍了一些对字符串处理的常用方法,在实际开发中还是会经常会遇到对字符串进行处理的需求,这样会使我们的开发更为高效。