目录
String是字符串类型,C语言中没有字符串类型。
Java中,没有说 字符串的结尾是"\0"这样的说法
C语言之所以有这样的规定,是因为C得用这个字符来判断结尾
1. 字符串构造
String类提供的构造方式非常多,常用的有以下三种:
public class Test {
public static void main(String[] args) {
//使用常量串构造
String str="hello";
//直接newString对象
String str2=new String("World");
//使用字符数组进行构造
char[] value={'1','2','3'};
String str3=new String(value);
System.out.println(str3);
System.out.println(str2);
System.out.println(str);
}
}
2. String对象的比较
字符串的比较:(==和equals())
public class Test {
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
System.out.println("============");
System.out.println(s1.equals(s2));//true(内容一样)
System.out.println(s1.equals(s2));//true
System.out.println(s2.equals(s3));//true
}
}
compareTo()比较字符串大小:
public class Test {
public static void main(String[] args) {
String s1=new String("hello");
String s2=new String("abcdef");
//对应字符比较
System.out.println(s1.compareTo(s2));//正数7
System.out.println(s2.compareTo(s1));//负数-7
//如果两个字符串相同,返回0
}
}
compareToIgnoreCase():与compareTo()相同,但是忽略大小写
3. 字符串查找
charAt():
public class Test {
public static void main(String[] args) {
String s = "hello";
//1.根据下标进行查找
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
System.out.print(c);//hello
}
/*char ch = s.charAt(0);//s的下标为0的字符
System.out.println(ch);//h*/
}
}
indexOf():
public class Test {
public static void main(String[] args) {
String s = "hello";
//返回第一次出现的下标
int index = s.indexOf('l');
System.out.println(index);//2
}
}
public class Test {
public static void main(String[] args) {
String s = "hello";
int index = s.indexOf('l', 3);
System.out.println(index);//3(从3下标开始找'l')
index = s.indexOf("ll");
System.out.println(index);//2
index = s.indexOf("ll", 3);
System.out.println(index);//-1
}
}
lastIndexOf():
public class Test {
public static void main(String[] args) {
String s = "abcbacacba";
int index = s.lastIndexOf('a');//从后往前找'a'的下标
System.out.println(index);//9
index = s.lastIndexOf("ab", 4);//从后往前找"ab"的下标
System.out.println(index);//0
}
}
4. 转化
4.1 数值转字符串
class Student {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
String s1 = String.valueOf(1);
String s2 = String.valueOf(2.1);
String s3 = String.valueOf(true);
System.out.println(s1);//1
System.out.println(s2);//2.1
System.out.println(s3);//true
String s4 = String.valueOf(new Student("yue", 10));//序列化:把对象变成字符串
System.out.println(s4);//Student{name='yue', age=10}
int data1=Integer.parseInt("123");
double data2=Double.parseDouble("123.45");
System.out.println(data1+1);//124
System.out.println(data2+1);//124.45
}
}
4.2 大小写转换(只针对字符)
public class Test {
public static void main(String[] args) {
String s="hello";
String s2=s.toUpperCase();//产生新的对象
System.out.println(s2);//HELLO
String s3="Hello";
String s4=s3.toLowerCase();
System.out.println(s4);//hello
}
}
4.3 字符串转数组
public class Test {
public static void main(String[] args) {
String s = "hello";
char[] array = s.toCharArray();
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");//h e l l o
}
}
}
4.4 格式化
public class Test {
public static void main(String[] args) {
String s2 = String.format("%d-%d-%d", 2024, 8, 3);
System.out.println(s2);//2024-8-3
}
}
5. 字符串替换
public class Test {
public static void main(String[] args) {
String s = "ababcabcd";
String tmp = s.replace('a', 'k');//把'a'替换成'k',也可以是字符串
System.out.println(tmp);//kbkbckbcd
tmp = s.replaceFirst("ab", "ooo");//替换第一个"ab"
System.out.println(tmp);//oooabcabcd
}
}
6. 字符串拆分
public class Test {
public static void main(String[] args) {
String s = "2024 08 03";
String[] Strings = s.split(" ");//拆分,返回值是数组
for (int i = 0; i < Strings.length; i++) {
System.out.print(Strings[i]);//20240803
}
}
}
不是正则表达式时,需要加上"\\":
public class Test {
public static void main(String[] args) {
String s = "127.0.0.1";
String[] strings = s.split("\\.");
for (int i = 0; i < strings.length; i++) {
System.out.print(strings[i] + " ");//127 0 0 1
}
}
}
注意:
- 字符"|","*","+"都得加上转义字符,前面加上"\\"
- 如果是"\",就要加上"\\\\"
- 如果一个字符串有多个分隔符,可以用"|"作为连字符
public class Test {
public static void main(String[] args) {
String s = "ab\\cd\\ef";
System.out.println(s);//ab\cd\ef
String[] strings = s.split("\\\\");
for (int i = 0; i < strings.length; i++) {
System.out.print(strings[i] + " ");//ab cd ef
}
}
}
public class Test {
public static void main(String[] args) {
String s = "name=tom&age=10";
String[] strings = s.split("&|=");
for (int i = 0; i < strings.length; i++) {
System.out.print(strings[i] + " ");//name tom age 10
}
}
}
7. 字符串截取
public class Test {
public static void main(String[] args) {
String s = "abcdef";
String s2 = s.substring(2);//从2下标开始截取
System.out.println(s2);//cdef
String s3 = s.substring(0, 2);//[0,2)
System.out.println(s3);//ab
}
}
trim():去掉字符串中的左右空格,保留中间空格。
public class Test {
public static void main(String[] args) {
String s = " abc d ef";
String s2 = s.trim();//只去除左右两边的空格
System.out.println(s2);//abc d ef
}
}
8. 字符串的不可变性
有人说:字符串不可变是因为其内部保存字符的数组被final修饰了。这种说法是错误的。不是因为String类本身,或者其内部value被final修饰而不可修改。
final修饰类表名类不能被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容可以修改。
是因为value被private修饰,不能被其它类进行引用。
9. 字符串修改
public class Test {
public static void main(String[] args) {
String s = "hello";
s += "world";
System.out.println(s);//helloworld
}
}
这种方法不推荐使用,效率非常低,中间创建了好多临时对象。
底层代码如下:
public class Test {
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("hello");
stringBuilder.append("world");
String ret = stringBuilder.toString();
System.out.println(ret);//helloworld
}
}
public class Test {
public static void main(String[] args) {
long start = System.currentTimeMillis();//毫秒
String s = "";
for (int i = 0; i < 10000; i++) {
s += i;
}
long end = System.currentTimeMillis();
System.out.println(end - start);//69
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);//1
start = System.currentTimeMillis();
StringBuilder sbd = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sbd.append(i);
}
end = System.currentTimeMillis();
System.out.println(end - start);//0
}
}
以上代码可以看出,对String类进行修改时,效率非常慢,因此:尽量避免对String的直接修改,尽量使用StringBuffer或者StringBuilder。
public class Test {
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder("abcdef");
stringBuilder.reverse();//对当前对象进行修改
System.out.println(stringBuilder);//fedcba
stringBuilder.insert(0, "def");//从下标为0的位置插入
System.out.println(stringBuilder);
}
}
从上述例子可以看出:String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder.
注意:String和StringBuilder类不能直接转换。若要相互转换,可采用以下原则:
- String变为StringBuilder:利用StringBuilder的构造方法或append()方法
- StringBuilder变为String:调用toString()方法
StringBuffer用于多线程情况下,可以保证线程安全
StringBuilder用于单线程情况下,不能保证线程安全