【浅学Java】Java中 String类 的总结
01. 字符串构造
String类提供的构造方法非常多,常见的构造方法有三种:
public static void main(String[] args) { //使用常量字符串构造 String s1="hello"; System.out.println(s1); //直接newString对象 String s2=new String("world"); System.out.println(s2); //使用字符数组进行构造 char [] ch= new char[]{ b,i,t}; String s3=new String(ch); System.out.println(s3); }
注意:
- String是引用类型,内部并不存储字符串本身
- 在Java中“”引起来的也是String类型对象,比如:
System.out.println("hello".length());
02. String对象的比较
在Java中,共提供4种方式进行字符串的比较:
1. ==比较是否引用同一个对象
public static void main(String[] args) { String s1="hello"; String s2="hello"; System.out.println(s1==s2); String s3=new String("world"); String s4=new String("world"); System.out.println(s3==s4); }
运行结果: 至于为啥第一个是true,第二个为啥是false,后面我们会说到。 在这里我们只要知道:true说明s1和s2引用同一个对象,false说明s3和s4引用不同的对象。
2. equals方法:按照对象的内容是否一样进行比较
String类重写了父类Object中的 equals方法,Object中的equals默认按照 == 比较,String重写之后按照对象的内容是否一样进行比较:s1.equals(s2)
public static void main(String[] args) { String s1="hello"; String s2="hello"; System.out.println(s1.equals(s2)); String s3=new String("world"); String s4=new String("world"); System.out.println(s3.equals(s4)); }
运行结果: 由运行结果可以说明: s1所引用对象的内容和s2所引用对象的内容一样; s3所引用对象的内容和s4所引用对象的内容一样;
3. compareTo方法
与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:
- 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
- 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值
public static void main(String[] args) { String s1="hello"; String s2="hello"; System.out.println(s1.compareTo(s2)); String s3=new String("world"); String s4=new String("wOrlT"); System.out.println(s3.compareTo(s4)); }
第一组比较:s1和s2所引用对象的内容一样,故结果为0; 第二组比较:s3和s4在第二个字符处不同,即’ O ’ 和 ‘o’ 不一样,所以返回两个字符的差值
4. compareToIgnoreCase方法
与compareTo方式相同,但是忽略大小写比较
public static void main(String[] args) { String s1="hello"; String s2="HELLO"; System.out.println(s1.compareToIgnoreCase(s2)); }
03. 字符串查找
字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:
public static void main(String[] args) { String s = "aaabbbcccaaabbbccc"; System.out.println(s.charAt(3)); // b System.out.println(s.indexOf(c)); // 6 System.out.println(s.indexOf(c, 10)); // 15 System.out.println(s.indexOf("bbb")); // 3 System.out.println(s.indexOf("bbb", 10)); // 12 System.out.println(s.lastIndexOf(c)); // 17 System.out.println(s.lastIndexOf(c, 10)); // 8 System.out.println(s.lastIndexOf("bbb")); // 12 System.out.println(s.lastIndexOf("bbb", 10)); // 3 }
运行结果:
04. 转换
1. 数值和字符串转换
public static void main(String[] args) { String s1=String.valueOf(1234); String s2=String.valueOf(12.34); String s3=String.valueOf(true); System.out.println(s1); System.out.println(s2); System.out.println(s3); System.out.println("=========="); int data1=Integer.valueOf("1234");//或者Integer.parseInt double data2=Double.valueOf("12.34");//或者Integer.parseDouble System.out.println(data1); System.out.println(data2); }
运行结果:
2. 大小写转换
public static void main(String[] args) { String s1="hello"; System.out.println(s1.toUpperCase()); String s2="WORLD"; System.out.println(s2.toLowerCase()); }
3. 字符串数组
public static void main(String[] args) { String s1="hello"; //字符串转数组 char []ch=s1.toCharArray(); for(int i=0;i<ch.length;i++){ System.out.print(ch[i]); } System.out.println(); //数组转字符串 String s2=new String(ch); System.out.println(s2); }
4. 格式化
public static void main(String[] args) { String s=String.format("%d-%d-%d",2022,4,15); System.out.println(s); }
05. 字符串替换
使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:
public static void main(String[] args) { String str="abababcadbca"; //将所有的ab替换为mp System.out.println(str.replaceAll("ab","mp")); //将第一个ab替换为mp System.out.println(str.replaceFirst("ab","mp")); }
运行结果:
06.字符串拆分
可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串 可用方法如下:
- String[] split(String regex)————将字符串全部拆分
- String[] split(String regex, int limit)—————将字符串以指定的格式,拆分为limit组
示例1:按照空格拆分
public static void main(String[] args) { String str="hello world hello bit"; String [] result=str.split(" "); for(String s:result){ System.out.println(s); } }
示例2:按照空格拆分为2个部分
public static void main(String[] args) { String str="hello world hello bit"; String [] result=str.split(" ",2); for(String s:result){ System.out.println(s); } }
示例3:拆分IP地址
public static void main(String[] args) { String str="192.123.45.32"; String [] result=str.split("\."); for(String s:result){ System.out.println(s); } }
注意事项:
- 字符"|","*","+"都得加上转义字符,前面加上 “” .
- 而如果是 “” ,那么就得写成 “\” .
- 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
示例4:多次拆分
public static void main(String[] args) { String str="name=zhangsan&age=18" ; String [] result1=str.split("=");//先用=拆分 for (String temp1:result1) { String []result2 = temp1.split("&");//再用&拆分 for(String temp2:result2 ){ System.out.println(temp2); } } }
07. 字符串截取
从一个完整的字符串之中截取出部分内容。可用方法如下:
String substring(int beginIndex)————从指定索引截取到结尾 String substring(int beginIndex, int endIndex)————截取部分内容
public static void main(String[] args) { String s="helloworld"; System.out.println(s.substring(5));//从5下标开始截取,即从w开始 System.out.println(s.substring(0,5));//截取[0,5)区间的内容 }
08. trim操作
去掉字符串中的左右空格,保留中间空格
public static void main(String[] args) { String str = " hello world " ; System.out.println("["+str+"]"); System.out.println("["+str.trim()+"]"); }
运行结果:
09. 字符串的不可变性
String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:
String类在设计时就是不可改变的,String类实现描述中已经说明了: String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:
- String类被final修饰,表明该类不能被继承
- value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改
那么字符串不能被修改的根本原因是什么呢? 是因为:value【】数组被private修饰,访问权限只在String类中,外界要想操作value的内容就得String向外提供get或者set接口,但是String并没有提供。
10. 字符串修改
注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下。
public static void main(String[] args) { String s = "hello"; s += " world"; System.out.println(s); // 输出:hello world }
但是这种方式不推荐使用,因为其效率非常低,中间创建了好多临时对象。
11. StringBuilder和StringBuffer
String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。
注意: String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:
- String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
- StringBuilder变为String: 调用toString()方法
面试题1. String、StringBuffer、StringBuilder的区别
- String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
- StringBuffer与StringBuilder大部分功能是相似的
- StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作
面试题2. 以下总共创建了多少个String对象【前提不考虑常量池之前是否存在】
String str = new String("ab"); // 会创建多少个对象 String str = new String("a") + new String("b"); // 会创建多少个对象
分析: 第一个:"ab"在常量池创建1个对象,new创建一个对象共2个 第二个:“a”,"b"在常量池中各创建1个对象,2个new创建两个对象,然后在字符串相加时会再创建一个StringBuilder临时对象,最后会利用toString创建一个String对象,即一共6个对象