一、String的特性
-
String是一个final类,代表不可变的字符序列。
体现一:当对字符串重新赋值时,需要重写制定内存区域赋值,不使用原有的value进行赋值。
体现二:当对现有字符串进行连接操作时,也需要重新指定内存区域,不使用原有的value进行赋值。
体现三:当调用String的replace()方法修改指定字符时,也需要重新指定内存区域,不使用原有的value进行赋值。 -
String可以通过字面量的方式(区别new)给一个字符串赋值。
public void test(){
//通过字面量定义的方式:此时s1和s2的数据声明在方法区中的字符串常量池中
String s1="javaEE":
String s2="javaEE":
//通过new+构造器的方式:此时的s3和s4保存的地址值是数据在堆空间中开辟以后对应地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
//"=="比较两个变量的地址
System.out.println(s1==s2);//true
System.out.println(s1==s3);//false
System.out.println(s1==s4);//false
System.out.println(s3==s4);//false
}
public void test(){
String s1="hello";
String s2="world";
String s3="helloworld";
String s4="hello"+"world";
String s5=s1+"world";
String s6="hello"+s2;
String s7=s5.intern();//返回得到的s7使用已经在常量池中存在的“helloworld”
System.out.println(s3==s4);//true
System.out.println(s3==s5);//false
System.out.println(s5==s6);//false
System.out.println(s1==s2);//false
System.out.println(s7==s3);//true
//结论:
1.常量与常量的连接结果还在常量池中,且常量池中不会存在相同内容的常量
2.只要其中有一个变量,结果就在堆中
3.如果拼接的结果调用intern()方法,返回值则在常量池中
}
- String对象的字符内容是存储在一个字符数组value[]中。
- String实现了Serializable接口(表示字符串是支持序列化的),实现了Comparable接口(表示String可以比较大小)。
二、String的常用方法
常用方法1
1. int length()//返回字符串的长度
2. char charAt(int index) //返回某索引处的字符
3. boolean isEmpty()//判断是否是空字符串
4. String toLowerCase()//将String中的所有字符转换为小写
5. String toUpperCase()//将String中的所有字符转换为大写
6. String trim()//返回字符串的副本,忽略前导空白和尾部空白
7. boolean equals(Object obj)//比较字符串的内容是否相同
8. boolean equalsIgnoreCase(String anotherString)//与equals类似,忽略大小写
9. String concat(String str)//将指定字符串连接到此字符串的结尾(等价于用“+”)
10. int compareTo(String anotherString)//比较两个字符串的大小(ascll码)
11. String subString(int beginIndex)//返回一个新的字符串,它是此字符串从beginIndex开始截取到结尾的子串
12. String subString(int beginIndex,int endIndex)//返回一个新字符串,它是此字符串从beginIndex到endIndex的子串
常用方法2
1. boolean endsWith(String suffix)//测试此字符串是否以指定的后缀结束 boolean
2. startsWith(String prefix)//测试此字符串是否以指定的前缀开始 boolean startsWith(String
3. prefix,int toffset)//测试此字符串从指定索引开始的子串是否以指定前缀开始
4. boolean contains(CharSequence s)//当且仅当此字符串包含指定char值序列时返回true
5. int indexOf(String str)//返回指定子串在此字符串中第一次出现的索引
6. int indexOf(String str,int fromIndex)//从指定索引开始,返回指定子串在此字符串中第一次出现的索引
7. int lastIndexOf(String str)//返回指定子串在此字符串最右出现处的索引
8. int lastIndexOf(String str,int fromIndex)//从指定索引开始,返回指定子串在此字符串最右出现处的索引
常用方法3
//替换
1. String replace(char oldChar,char
newChar)//返回一个新的字符串,它是newChar替换此字符串中出现的所有oldChar
2. String replace(CharSequence target,CharSequence replacement)//使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子串
3. String replaceAll(String regex,String replacement)//使用给定的replacement替换此字符串中所有匹配给定的正则表达式的子串
4. String replaceFirst(String regex,String replacement)//使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子串
//匹配
5. boolean matches(String regex)//告知此字符串是否匹配给定的正则表达式
//切片
6. String split(String regex)//根据给定的正则表达式的匹配拆分此字符串
7. String split(String regex,int limit)//根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下全部都放到最后一个元素中。
三、 String与其他类型的转换
1.String与基本数据类型、包装类转换
(1)String ->基本数据类型、包装类
调用包装类的静态方法:parseXXX(str)
public void test(){
String str="123";
int num=Integer.parseInt(str);
}
(2)基本数据类型、包装类->String
调用String重载的valueOf(XXX)
public void test(){
String str1="123";
int num=Integer.parseInt(str1);
String str2=String.valueOf(num);//"123"
}
2.String与char[]之间的转换
(1)String->char[]
调用String的toCharArray()方法
public void test(){
String str1="123";
char[] charArray=str1.tocharArray();
for(int i=0;i<charArray.length;i++){
System.out.print(charArray[i]);//123
}
}
(2)char[]->String
调用String的构造器
public void test(){
Char[] arr=new char[]{'h','e','l','l','o'};
String str2=new String(arr);
System.out.println(str2);//hello
}
3.String与byte[]之间的转换
(1)String->byte[](编码)
调用String的getBytes()
public void test(){
String str1="abc123中国";
byte[] bytes=str1.getBytes();//使用默认字符集(如UTF-8)
System.out.println(Arrays.toString(bytes));
//[97,98,99,49,50,51,-28,-72,-83,-27,-101,-67]
//后六位为“中国”两个汉字的Ascll码表示(使用默认字符集)
str1.getBytes("gbk")//可以指定编码字符集
}
(2)byte[]->String(解码)
调用String的构造器
public void test(){
String str1="abc123中国";
byte[] bytes=str1.getBytes();//使用默认字符集(如UTF-8)
byte[] gbks=str1.getBytes("gbk")//可以指定编码字符集
String str2=new String(bytes);//使用默认的字符集进行解码
System.out.println(Str2);//无乱码
String str3=new String(gbks);//使用默认的字符集进行解码
System.out.println(Str3);//编码时用gbk,解码时用默认UTF-8,则会产生乱码
String str4=new String(gbks,"gbk");//使用gbk字符集进行解码
System.out.println(Str4);//无乱码
}
四、String相关的类
1.String、StringBuffer、StringBuilder底层源码分析
String str=new String();//char[] value=new char[0];
String str1=new String("abv");//char[] value=new char[0]{'a','b','c'};
StringBuffer sb1=new StringBuffer();
//char[] value=new char[16];底层创建了一个长度为16的字符数组
System.out.println(sb1.length());
//0 length方法得到的是内置元素的长度,不是16
sb1.append('a');//value[0]='a';
sb1.append('b');//value[1]='b';
StringBuffer sb2=new StringBuffer("abc");
//char[] value=new char["abc".legth()+16];底层创建了一个长度为初始字符长度+16的字符数组
扩容问题:如果添加的数据底层数组盛不下了,那就需要扩容底层数组。
默认情况下,扩容为原来容量的2倍+2,同时将原有数组中的元素复制到新的数组中。
为了避免扩容,建议开发中使用:StringBuffer/StringBuilder(int capacity)构造器指定容量大小
2.StringBuffer/StringBuilder类比较
StringBuffer可变的字符序列,线程安全,效率低,使用char[]存储。
StringBuilder可变的字符序列,线程不安全,效率高,使用char[]存储,jdk5.0新增。
效率: StringBuilder>StringBuffer>String
public void test(){
StringBufer sb1=new StringBuffer("abc");
sb1.setCharAt(0,'m');
System.out.println(sb1);//mbc
//说明StringBuffer为可变字符序列
}
3.StringBuffer/StringBuilder常用方法
1. 增:StringBuffer append(xxx)//用于进行字符串拼接
2. 删:StringBuffer delete(int start,int end)//删除指定位置的内容
3. 改:StringBuffer replace(int start,int end,String str)//把(start,end)位置替换为str
4. 插:StringBuffer insert(int offset,xxx)//在指定位置插入xxx
5. StringBuffer reverse()//把当前字符序列逆转
6. int indexOf(String str)//同String
7. String substring(int start,int end)//同String
8. int length()//同String
9. 查:char charAt(int n)//同String
10.改:void setCharAt(int n,char ch)//同String
11.遍历:toString();