欢迎来到我的博客~ 欢迎大家对我的博客提出意见和建议哦
目录
一、String类的重要性
在C语言中已经涉及到字符串了,但是在C语言中要表示字符串只能使用字符数组或者字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想,而字符串应用又非常广泛,因此Java语言专门提供了String类。
二、常用方法
2.1字符串构造
String类提供的构造方式非常多,常用的就以下三种:
public class Main {
public static void main(String[] args) {
// 使用常量串构造
String s1 = "hello world!";
System.out.println(s1);
// 直接newString对象
String s2 = new String("hello world!!");
System.out.println(s2);
// 使用字符数组进行构造
char[] arrays = {'h','e','l','l','o'};
String s3 = new String(arrays);
System.out.println(s3);
}
}
2.2字符串的比较
2.2.1 比较两者是否是同一个对象(==)
同一个对象比较为true,不同对象比较为false。
public class Main {
public static void main(String[] args) {
String s1=new String("hello!");
String s2=new String("hello!!");
String s3=s1;
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//true
System.out.println(s2 == s3);//false
}
}
2.2.2 比较两者是否是内容一样 (eauals)
内容相同为true,不同内容为false。
public class Main {
public static void main(String[] args) {
String s1=new String("hello!!");
String s2=new String("hello!");
String s3=s1;
System.out.println(s1.equals(s2));//false
System.out.println(s1.equals(s3));//true
System.out.println(s2.equals(s3));//false
}
}
2.2.3 compareTo 比较字符大小
与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值。
public class Main {
public static void main(String[] args) {
String s1 = "abcd";
String s2 = "abde";
System.out.println(s1.compareTo(s2));//d的字符比c的大-->s1<s2 输出负数
String S3 = "ABC";
String S4 = "ABC";
System.out.println(S3.compareTo(S4));//相同为0;
String s5 = "abdefg";
String s6 = "abde";
System.out.println(s5.compareTo(s6));//2--> 如果前面字符相等,返回值两个字符串长度差值。
}
}
2.2.4 compareToIgnoreCase(String str) 方法
与compareTo方式相同,但是忽略大小写比较
public class Main {
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.compareToIgnoreCase(s2)); // 不同输出字符差值-1
System.out.println(s1.compareToIgnoreCase(s3)); // 相同输出 0
System.out.println(s1.compareToIgnoreCase(s4)); // 前面字符完全相同,输出长度差值 -3
}
}
2.3 字符串查找
字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:char charAt(int index)、int indexOf(int ch)、int indexOf(int ch,int fromlndex)等等…
public class Main {
public static void main(String[] args) {
String s1 = "abcdefdeca";
//返回下标为1对应的字符
System.out.println(s1.charAt(1));
//返回第一次出现‘c’的位置下标
System.out.println(s1.indexOf('c'));
//从下标为fromIndex开始找第一次出现”e“的位置,没有则返回-1,有则返回对应的下标
System.out.println(s1.indexOf("e", 1));
//返回第一次出现“f”的位置
System.out.println(s1.indexOf("f"));
//从后面往前面找,返回第一次出现“f”的位置
s1.lastIndexOf("f");
}
}
上面字符串的查找不止这些,其他的查找可以去查阅了解
2.4 转换
2.4.1 数值和字符串转化
//数字转字符串
String s1 = String.valueOf(123);
String s2 = String.valueOf('b');
String s3 = String.valueOf(12345f);
String s4 = String.valueOf(true);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
System.out.println("=========");
//字符串转数字
int a = Integer.parseInt("123");
double d = Double.parseDouble("123.4");
System.out.println(a);
System.out.println(d);
2.4.2大小写转换
//小写转换成大写
String s1="abc";
System.out.println(s1.toUpperCase());
System.out.println("=========");
//大写转换成小写
String s2="ABC";
System.out.println(s2.toLowerCase());
2.4.3 字符串数组之间的转换
String s1="abcdf";
char[] ch=s1.toCharArray();
//字符串转数组
for (int i = 0; i < ch.length; i++) {
System.out.print(ch[i]);
}
//数组转字符串
String s2=new String(ch);
System.out.println(" "+s2);
}
2.4.4 格式化
String s1=String.format("%d-%d-%d",2024,11,05);
System.out.println(s1);
2.5字符串替换
//字符串替换
String s="aabbccdefghjk";
//把所有"a"替换成"e"
System.out.println(s.replaceAll("a", "e"));
//替换一个"b"
System.out.println(s.replaceFirst("b", "6"));
注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串。
2.6 字符串拆分
可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
public static void main(String[] args) {
String s1 = "hello world !!!";
//将字符串按照空格全部拆分
String[] a = s1.split(" ");
for (String x : a) {
System.out.println(x);
}
System.out.println("=======");
//将字符串以指定的格式,拆分成n组
String[] s2 = s1.split(" ", 2);
for (String y : s2) {
System.out.println(y);
}
System.out.println("=======");
//拆分IP地址
String s3 = "192.168.128.128";
String[] s4 = s3.split("\\.");
for (String z : s4) {
System.out.println(z);
}
//多次拆分
String str = "name=zhangsan&age=18";
String[] result = str.split("&");
for (int i = 0; i < result.length; i++) {
String[] temp = result[i].split("=");
System.out.println(temp[0] + " = " + temp[1]);
}
}
注意事项:
- 字符"|“,”*“,”+"都得加上转义字符,前面加上 “\” .
- 而如果是 “” ,那么就得写成 “\\” .
- 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
2.7字符串截取
public static void main(String[] args) {
//字符串截取
String s1 = "hello world !!!";
//从下标为2的字符串开始截取
System.out.println(s1.substring(2));
System.out.println("=========");
//从下标为2的字符串开始截取到下标为5
System.out.println(s1.substring(2,5));
}
注意事项:
- 索引从0开始
- 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标.
2.8字符串的不可变性
String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:
1. String类在设计时就是不可改变的,String类实现描述中已经说明了
以下来自JDK1.8中String当中的部分实现:
String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:
- String类被final修饰,表明该类不能被继承
- value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。
所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象。
比如 replace 方法:
【纠正】网上有些人说:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改。
final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。
那如果想要修改字符串中内容,该如何操作呢?
2.9 字符串的修改
注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下。
public static void main(String[] args) {
String s="hello";
s+=" world";
System.out.println(s);
}
这种方式不推荐使用,因为其效率非常低,中间创建了好多临时对象。
再看一组代码:
public static void main(String[] args) {
//String类
long start=System.currentTimeMillis();//毫秒
String s=" ";
for (int i = 0; i < 10000; i++) {
s+=i;
}
long end=System.currentTimeMillis();
System.out.println(end - start);
//StringBuffer类
start=System.currentTimeMillis();
StringBuffer sbf=new StringBuffer(" ");
for (int i = 0; i < 10000; i++) {
sbf.append(i);
}
end=System.currentTimeMillis();
System.out.println(end - start);
//StringBuilder类
StringBuilder sbd=new StringBuilder(" ");
for (int i = 0; i < 10000; i++) {
sbd.append(i);
}
end=System.currentTimeMillis();
System.out.println(end - start);
}
可以看到在对String类进行修改时,效率是非常慢的,因此:尽量避免对String的直接需要,如果要修改建议尽量使用StringBuffer或者StringBuilder。
2.10 StringBuilder和StringBuffer
①当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
②和 String 类不同的是,StringBuffer 和 StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象。
③StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
④由于 StringBuilder 相较于 StringBuffer 有速度优势,多数情况下建议使用StringBuilder类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
public class RunoobTest{
public static void main(String[] args){
StringBuilder sb = new StringBuilder(10);
sb.append("Runoob..");
System.out.println(sb);
sb.append("!");
System.out.println(sb);
sb.insert(8, "Java");
System.out.println(sb);
sb.delete(5,8);
System.out.println(sb);
}
}
然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
public class RunoobTest{
public static void main(String[] args){
StringBuilder sb = new StringBuilder(10);
sb.append("Runoob..");
System.out.println(sb);
sb.append("!");
System.out.println(sb);
sb.insert(8, "Java");
System.out.println(sb);
sb.delete(5,8);
System.out.println(sb);
}
}
以下是 StringBuffer 类支持的主要方法:
欧耶!!我学会啦!!!