String 类型解析
String不可变性
下方为String类型源码的简洁版
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
由此看出,String类型数据不可变原因有两点:
- String类型被final 修饰,说明任何对String类型的操作不能被继承和重写。
- String类中用于存储数据是用final和private修饰的char类型数组value。value被final修饰说明value一旦被赋值,内存中无法更改。value被private修饰说明外部无法访问,且String类为开放value外部赋值的方法,所以外部无法赋值。
因为String的 不可变性,每次对String进行修改都要用新变量存储返回值。
String相等判断: equals函数
源码如下:
public boolean equals(Object anObject) {
//判断this字符串和anObject内存地址是否相等
if (this == anObject) {
return true;
}
// 判断anObject是否为String类型
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;
}
- equals函数和==判断字符串相等的区别?
如上方源码所示,==比较两个变量地址是否相等,地址相等的两个变量,值一定相等。equals函数比较两个变量的函数值是否相等,两个变量的值相等,地址不一定相等。 - equalsIgnoreCase函数做相等判断时忽略大小写。
replace函数
replace方法共有replace、replaceAll、replaceFirst三种,传入参数不同,为方便记忆可都传入字符串格式。
public void testReplace(){
String s="hello world.";
System.out.println("替换前字符串为"+s);
//replace能传入字符和字符串
s=s.replace('l','p');
System.out.println("替换单个字母"+s);
//replaceAll只能传入字符串
s=s.replaceAll("p","x");
System.out.println("替换全部"+s);
//replaceFirst只能传入字符串
s=s.replaceFirst("x","y");
System.out.println("替换第一个字母"+s);
}
运行结果如下:
split 函数
split(String s,int n),s为切割的字符,n为拆分的元素个数,如果缺失n参数,则拆分字符串中所有分割字符。
String s="ss,aa,tt,fd,d,,d";
//切割结果["ss","aa","tt","fd","d","","d"]
s.split(",");
//切割结果["ss","aa","tt,fd,d,,d"]
s.split(",",3);
//切割结果["ss","aa","tt","fd","d","","d"]
s.split(",",10);
//切割结果["ss","aa","tt","fd","d","","d"]
s.split(",",-2);
substring 函数
substring(int begin, int end),取子串的范围[begin,end),如果没有end参数,则从开始位置取子串到末尾。
测试程序如下:
public void testSubstring(){
String s="01234567";
System.out.println("取子串1:"+s.substring(1,5));
System.out.println("取子串2:"+s.substring(2));
}
测试结果为: