String类
文章目录
1 创建字符串
创建字符串有很多种方式:
//方法一:
String str = "hello";
//方法二:
String str2 = new String("hello world");
//方法三:
//Java种的字符串和字符数组之间没有任何关联关系
char[] array = {'a', 'b', 'c'};
String str3 = new String(array);
常用的就是第一种方式
更多的创建方式可以查看Java的api文档:https://docs.oracle.com/javase/8/docs/api/index.html
2 字符串的比较
Java中如果针对引用类型使用 == ,此时比较的是两个引用的地址是否相等
String a = "hello";
String b = "hello";
//此时的比较是直接比较 a 和 b 引用里面存的地址是否相等
System.out.println(a == b);//输出 true
Java的字符串常量会被保存在“字符串常量池”里,字符串常量只需要保存一份,上面这段代码 a 和 b 指向的是字符串常量池中 hello 的地址,所以地址是相同的
常量池是 JVM 划分的一个内存区域,JVM 运行时会专门划分一个区域作为常量池,也是堆的一部分
String c = new String("hello");
String d = new String("hello");
System.out.println(c == d);//输出 false
上面这段代码 c 和 d 是我们手动创建的字符串,地址是不同的
如果要比较两个字符串的内容,就需要用 .equals 方法
System.out.println(a.equals(b));//输出 true
调用 intern 方法,就会拿着当前这个字符串里的内容在字符常量池中找,看当前这个字符串是不是在池中,如果在池中直接返回该池中的地址,如果不存在,则把当前字符串加到常量池中,返回池中的地址
String a = new String("hello").intern();
System.out.println(a == "hello");//输出 true
3 String 的不可变特性
Java的 String 是不可变的(对象本身不可修改),与 final 是不一样的,final 修饰的是一个引用的话,引用指向的地址不能改变,但是地址中保存的对象是可以被修改的
String 设计成不可变:
1、方便放到池中,如果是可变对象,一旦池中的内容发生改变,就会影响到所有引用这个池中对象的结果
2、对象内容不可变,则对象的 hashCode 也不可变,方便和 hash 表这样的结构配合使用
3、对象不可变,线程安全更有保证
但是利用“反射”这种手段也不是不能改变,反射 是面向对象程序设计的一个重要的特性
String str = "hello";
//通过反射修改“hello”的内容
//1) 获取到 String 的类对象
//2) 根据 "value" 这个字段名字,在类对象中拿到相应的字段
Field valueField = String.class.getDeclaredField("value");
//让 value 这个 private 的成员也能被访问到
valueField.setAccessible(true);
//3) 根据图纸,把 str 这个对象拆开,得到里面的零件
char[] value = (char[])valueField.get(str);
//4) 修改零件的内容
value[4] = 'a';
System.out.println(str);
4 字符和字符串之间的转变
4.1 字符转变为字符串
使用一个字符数组来构造成字符串
char[] value = {'a', 'b', 'c'};
String s = new String(value);
4.2 字符串获取到字符
使用 charAt 来获取到指定下标位置的字符
使用 toCharArray 获取到字符数组
//方法1
String s = "abcd";
System.out.println(s.charAt(0));
System.out.println(s.charAt(1));
System.out.println(s.charAt(2));
System.out.println(s.charAt(3));
// 使用 .length() 方法获取到字符串长度,数组的长度是用 .length 属性获取
System.out.println(s.length());
//方法2
// toCharArray 方法相当于在内部创建了一个新的字符数组并返回
//修改这个返回值不会影响 s 本身的内容
char[] value = s.toCharArray();
for(char v: value){
System.out.println(v);
}
//验证一下
value[0] = 's';
System.out.println(s);
5 字符串比较大小
字符串大小判定的规则:
按照字典序,先比较首个字符的大小(看字符的 Unicode 的值的大小),如果首个字符能分出大小关系,两个字符串的大小就确定了,如果首个字符不能分出大小,继续比较下一个字符
用 compareTo 进行字符串比较,不忽略大小写
String a = "hello";
String b = "hallo";
//compareTo 返回的是一个 int
//如果 a 比 b 小,返回一个小于 0 的结果
//a 比 b 大, 返回一个大于 0 的结果
int result = a.compareTo(b);
System.out.println(result);
忽略大小写的比较可以用 compareToIgnoreCase 或者 equalsIgnoreCase
String c = "hello";
String d = "HeLLO";
//忽略大小写的比较
boolean result3 = c.equalsIgnoreCase(d);
System.out.println(result3);
int result2 = c.compareToIgnoreCase(d);
System.out.println(result2);
contains
indexOf, 返回的是字符串的起始位置,如果存在多个相同的字符串,返回的是最左边的也就是第一个出现的, 没找到就返回 -1
lastIndexOf, 从后往前查找
startsWith 判断是不是以指定的字符串开始
endWith 判断是不是以指定的字符串结束
典型用法:
1、判断某个链接的协议类型,会使用 startsWith
2、判断某个文件的类型,会使用 endWith 判断文件扩展名
6 对字符串操作
6.1字符串替换
字符串替换,由于 String 是不可变对象,针对字符串的替换操作并没有修改字符串本身,而是生成了一个新的字符串
replaceAll : 将 a 中所有的 b 字符串替换成指定字符串
replaceFirst :将 a 中第一个出现的 b 字符串替换成指定字符串
String result = a.replaceAll(b, "java");
System.out.println(result);//hello java java
System.out.println(a);//hello world world
String result1 = a.replaceFirst(b, "java");
System.out.println(result1);//hello java world
6.2 字符串拆分
按照分割符,将字符串分成几个部分,把这些部分放到一个数组中
split
String a = "hello world java";
String[] result = a.split(" ");
//[hello, world, java]
System.out.println(Arrays.toString(result));
6.3 字符串截取
substring
String a = "hello world java";
//[begin, end),包含 begin 不包括 end
System.out.println(a.substring(6, 11));//world
7 字符串修改
String 是不可变对象,不能直接修改内容,如果需要使用可变版本的 String 就需要使用 StringBuilder 或者 StringBuffer ,StringBuilder 和 StringBuffer 的用法基本一样
1
StringBuilder 和 StringBuffer 的区别:
StringBuilder 是线程不安全的
StringBuffer 是线程安全的
append 直接将参数拼接到字符串的末尾;
如果 append 拼接的内容太多,超出了内存范围,StringBuilder 会自动扩容
delete 删除指定区域的字符;
reverse 反转字符串;
insert 在指定位置插入字符串
//字符串反转
stringBuilder.reverse();
System.out.println(stringBuilder.toString());
//删除[1, 4)之间的字符串
//包含 1 不包含 4
stringBuilder.delete(1, 4);
System.out.println(stringBuilder.toString());
//在下标为 2 的地方插入字符串
stringBuilder.insert(2, "world");
System.out.println(stringBuilder.toString());