String
String是JAVA中最常用的对象,就是这样一个最常用最普通的对象,当你深入研究时却发现我们并不是真的很了解它,那么让我们一起来学习它吧!
因为String不可变的性质,因此Java内部实现了常量池。当一个String被创建时,会先去常量池查看有没有值相同的示例,有的话直接返回。节省了内存,加快了字符串的加载速度。不可变的对象也可以保证在并发中保持线程安全
特性
- 字符串常量,实际上也是String对象
- 所有不是通过new创建的String都是放在常量池中
- String类型的对象是不可变的
- String实现了CharSequence接口
String对象创建方式
String str1 = "abcd";
String str2 = new String("abcd");
这两种不同的创建方法是有差别的,第一种方式是在常量池中拿对象,第二种方式是直接在堆内存空间创建一个新的对象。
只要使用new方法,便需要创建新的对象
连接表达式+(加号)
- 只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。
- 对于所有包含new方式新建对象(包括null)的“+”连接表达式,它所产生的新对象都不会被加入字符串池中
String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";
String str4 = str1 + str2;
System.out.println(str3 == str4);//false
String str5 = "string";
System.out.println(str3 == str5);//true
1、 Sting s; //定义了一个变量s,没有创建对象;
2、 = // 赋值,将某个对象的引用(句柄)赋给s ,没有创建对象;
3、 “abc” //创建一个对象;
4、 new String(); // 创建一个对象。
常用方法
length 返回字符串长度
isEmpty 判断字符串是否为空
charAt 根据索引位置获取char
getChars 复制对应位置范围的char到数组中
equals, equalsIgnoreCase 对比顺序依次为引用地址,char数组长度,char数组内容
compareTo 对比字符串大小
startsWith, endsWith 判断前后缀
hashCode 计算hash值, 公式为s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]
indexOf 查找首次出现的位置
lastIndexOf 查找最后出现的位置
substring 返回子串(旧版本是返回一个引用在父串的一个新串,节省重新分配内存。但实际如果子串引用了一个占用极大的父串,会因为子串一直被使用导致父串没法被垃圾回收,新版本substring每次重新复制char数组)
concat 拼接字符串(拼接char数组,重新创建字符串)
replace 用新字符替换所有的旧字符(会先遍历一次char数组,寻找时候存在,再去替换,避免每次都要分配char数组)
matches 判断是否符合正则 (复用Pattern.matches()方法)
contains 判断是否包含子串(复用indexOf()方法)
replaceFirst 只替换一次
replaceAll 替换所有正则符合的地方
split 按照正则分割字符串
toLowerCase 返回小写
toUpperCase 返回大写
trim 去除前后空格
toCharArray 重新复制char数组返回
join(CharSequence delimiter, CharSequence… elements)
String.join(",", "you", "bao", "luo"); //out: you,bao,luo
equals(Object anObject)
String.equals()代码逻辑:
判断传入的对象与当前对象是否为同一个对象,如果是就直接返回true;
判断传入的对象是否为String,若不是则返回false(如果为null也不成立);
判断传入的String与当前String长度是否一致,若不一致则返回false;
循环对比两个字符串的char[]数组,逐个对比字符是否一致,若不一致则直接返回false;
循环结束没有找到不匹配的则返回true;
JDK8源码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
- intern():naive方法,直接返回常量池中的引用