String类总汇
性质
String:字符串,使用一对 “” 引起来表示
1.String声明为final的,不可被修饰
2.String实现了Serializable接口:表示字符串是支持序列化的。
实现了Comparable接口:表示String可以比较大小。
3.String内部定义了final char[] value 用于存储字符串数据
4.String:代表不可变的字符序列。简称:不可变性。
体现:
①当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。
②当对现有的字符串进行连接操作时,也需要重新指定内存区域进行赋值,不能使用原有的value进行赋值。
③当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域进行赋值,不能使用原有的value进行赋值。
5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
6.字符串常量池中是不会存储相同内容的字符串的。
String的实例化方式
方式一: 通过字面量定义的方式
方式二: 通过new+构造器的方式
person类:
public class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {//alt + shift + s
this.name = name;
this.age = age;
}
}
@Test
public void test2() {
//通过字面量定义的方式:此时的s1和s2的数据“javaEE”声明在方法区中的字符串常量池中。
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
System.out.println("**********************");
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true String重写了equals
System.out.println(p1.name==p2.name);//true
p1.name="jerry";
System.out.println(p1.name);//jerry
System.out.println(p2.name);//tom
}
提问:String s=new String(“abc”);方式创建对象,在内存中创建了几个对象?
答:两个,一个是堆空间中new结构,另一个是char[ ]对应常量池的数:“abc”。
字符串的特性
1.常量与常量的拼接结构在常量池。且常量池中不会存在相同内容的常量。
2.只要其中有一个是变量,结构就在堆中。
3.如果拼接的结果调用intern()方法,返回值就在常量池中。
@Test
public void test3(){
String s1="javaEE";
String s2="hadoop";
String s3="javaEEhadoop";
String s4="javaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="javaEE"+s2;
String s7=s1+s2;
System.out.println(s3==s4);//true
System.out.println(s3==s5);//false
System.out.println(s3==s6);//false
System.out.println(s3==s7);//false
System.out.println(s5==s6);//false
System.out.println(s5==s7);//false
System.out.println(s6==s7);//false
String s8=s5.intern();//返回值得到的s8使用的常量池中已存在“javaEEhadoop”
System.out.println(s3==s8);//true
String s9=s6.intern();
System.out.println(s3==s9);//true
//注意:
String x="javaEEhadoop";
final String xx="javaEE";//x:常量
String xxx=x+"hadoop";
System.out.println(x==xxx);//true 常量与常量的拼接结构在常量池
}
String类常用的方法
String类常用的方法1
1.int length():返回字符串的长度:return value.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):与equlas方法类似,忽略大小写。
9.String concat(String str):将指定字符串连接到此字符串的结尾。等价于“+”。
10.int compareTo(String anotherString):比较两个字符串的大小。
11. String substring(int beginIndex):返回一个新的字符串,他是此字符串从beginIndex开始截取。
12.String substring(int beginIndex,int endIndex):返回一个新字符串,它是此字符串从beginIndex到endIndex(不包含)的一个字符串。[ 左闭右开)。
@Test
public void test1(){
String s1="HelloWorld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(5));//W
System.out.println(s1.isEmpty());//false
String s2 = s1.toLowerCase();
System.out.println(s1);//HelloWorld 没有对s1本身进行修改,而是新造了一个s2
System.out.println(s2);//helloworld
String s3=" hello wo rld ";
String s4=s3.trim();
System.out.println(s3);//" hello wo rld "
System.out.println(s4);//"hello wo rld"
String s5="HelloWorld";
String s6="helloworld";
System.out.println(s5.equals(s6));//fasle
System.out.println(s5.equalsIgnoreCase(s6));//true
String s7=s6.concat("def");
System.out.println(s7);//helloworlddef
String s8="abc";
String s9="abe";
System.out.println(s8.compareTo(s9));//-2
String s10="千军万马一将在探囊取物有何难";
String s11=s10.substring(3);
System.out.println(s10);//千军万马一将在探囊取物有何难
System.out.println(s11);//马一将在探囊取物有何难
String s12=s10.substring(3,5);
System.out.println(s12);//马一
}
String类常用的方法2
1.boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。
2.boolean startWith(String prefix):测试此字符串是否以指定的前缀开始。
3.boolean startWith(String prefix,int toffset):测试此字符串是否以指定的前缀开始。
4.boolean contains(CharSequence s):当且仅当此字符串包含指定的char值序列时,返回true。
5.int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引,不存在返回-1。
6.int indexOf(String str,int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,fromIndex为查找的起点,不存在返回-1
7.int lastIndexOf(String str):返回指定子字符在此字符串中最右边出现的索引,不存在返回-1。
8.int lastIndexOf(String str,int fromIndex):返回指定子字符在此字符串中最右边出现的索引,从指定的索引开始方向搜索,不存在返回-1。
@Test
public void test3(){
String s1="helloworld";
boolean s2=s1.endsWith("ld");
boolean s3=s1.endsWith("le");
System.out.println(s2);//true
System.out.println(s3);//false
boolean s4=s1.startsWith("H");
boolean s5=s1.startsWith("h");
System.out.println(s4);//false
System.out.println(s5);//true
boolean b=s1.startsWith("ll",2);//从2开始,是不是以ll开头
System.out.println(b);//true
String aa="llo";
boolean bb=aa.contains(aa);
System.out.println(bb);//true
System.out.println(s1.indexOf("owo"));//4
System.out.println(s1.indexOf("o",5));//6
System.out.println(s1.lastIndexOf("l"));//8
System.out.println(s1.lastIndexOf("l",7));//3
}
String类常用的方法3
替换
1.String replace(char oldChar,char newChar):返回一个新的字符串,newChar替换oldChar。
2.String replace(String regex,String replacement):使用给点的replacement替换此字符串所有匹配给点正则表达式的子字符串。
3.String replaceFirst(String regex,String replacement):使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串。
@Test
public void test4(){
String str1="贾克斯贾";
String str2=str1.replace('贾','金');
System.out.println(str2);//金克斯金 所有'贾'都改成'金'
String str3=str1.replace("贾克","恩格");
System.out.println(str3);//恩格斯贾
}
匹配
1.boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
切片
1.String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。
2.String[] split(String regex,int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
字符串转换
String 与基本数据类型、包装类之间的转换。
String -->基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)。
基本数据类型、包装类 -->String:调用String重载的valueOf(xxx)。或者xxx+""。
@Test
public void test1(){
String str="123";
int num=Integer.parseInt(str);
String str2=String.valueOf(num);//"123"
//或者
String str3=num+"";
System.out.println(str3.getClass());
}
String 与字符数组(char [])转换
String ---> char[]:调用String的toCharArray()
char[] ---> String:调用String的构造器
@Test
public void test2(){
String str="abc123";
char[] charArray=str.toCharArray();
for (int i = 0; i <charArray.length ; i++) {
System.out.println(charArray[i]);
}
char[] arr=new char[]{'h','e','l','l','o'};
String str2 = new String(arr);
System.out.println(str2);//hello
}
String与byte[]之间的转换
编码:String --> byte[]:调用String的getBytes()。
解码:byte[] -->String:调用String的构造器。
@Test
public void test3(){
String str1="123abc";
byte[] bytes=str1.getBytes();
System.out.println(Arrays.toString(bytes));//[49, 50, 51, 97, 98, 99]
System.out.println("*************************");
String sb = new String(bytes);
System.out.println(sb);//123abc
}
注意:解码时,要求使用的字符集必须与解码时的字符集一致,否则会出现乱码。
StringBuilder类和StringBuilder类
String、StringBuffer、StringBuilder区别?
String:不可变的字符序列;底层使用char[]存储;
StringBuffer:可变的字符序列;线程安全,效率低;底层使用char[]存储;
StringBuilder:可变的字符序列;线程不安全,效率高(jdk5.0新增的);底层使用char[]存储;
源码分析:
String str=new String();//char[] value=new Char[0];
String str1=new String(“abc”);//char[] value=new char[]{‘a’,‘b’,‘c’};
StringBuffer sb1=new StringBuffer();//char[] value=new char[16];底层创建了一个长度是16的数组。
sb1.append(‘a’);//value[0]=‘a’;
sb1.append(‘b’);//value[1]=‘b’;
StringBuffer sb2=new StringBuffer(“abc”);//char[] value=new char[“abc”.length()+16];
问题1:
StringBuffer sb3=new StringBuffer(“abc”);
System.out.println(sb3.length());
运算结果:3。
问题2:
扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。默认情况下,扩容为原来容量的2倍+2,同时将原有数组中的元素复制到新的数组中。
对比String、StringBuffer、StringBuilder三者效率问题:
从高到低:StringBuilder >StringBuffer >String
StringBuffer类的常用方法
1.append(xxx):提供了额很多的append()方法,用于进行字符串拼接。
2.delete(int start,int end):删除指定位置的内容。
3.replace(int start,int end,String str):把[start,end)位置替换为str。
4. insert(int offset,xxx):在指定位置插入xxx。
5.reverse():把当前字符序列逆转。
6.另外跟String用法一样的方法,如:indexOf(String str);sbustring(int start,int end);length();charAt();setCharAt(int n,char ch)。
总结:
增:append(xxx)
删:delete(int start,int end)
改:setCharAt(int n,char ch)、replace(int start,int end,String str)
查:charAt()
插:insert(int offset,xxx)
长度:length()
*遍历:for()+charAt()、toString()