String类是Java内置的用来表示字符串的类,所有的字面量字符串,都是String类的实例实现。当然,我们也可以通过new一个新对象的方式,创建一个String实例。
publicclassApp{publicstaticvoidmain(String[]args){// 方式1:使用字面量Strings1="hello";// 方式2:newStrings2=newString("hi");}}需要注意的是,使用字面量创建的字符串,字符串会存储到内存的字符串常量池中。在Java有所谓“享元模式”(共享元素),即两个变量如果引用相同的字符串内容,系统会指向同一个字符串常量池中内的字符串。证明如下:
publicclassDemo0{publicstaticvoidmain(String[]args){// 用字面量创建一个String对象Strings1="hello";// 用字面量创建另外一个String对象,字符串内容完全相同Strings2="hello";// 证明两个变量都是同一个对象的引用System.out.println(s1==s2);// true}}而如果不是用的字面量,是用new创建两个String对象,则是完全不同的结果。用new创建两个字符串内容完全相同的String对象,会在内存堆里存储对象。两个变量则是完全不同的对象。证明如下:
publicclassDemo1{publicstaticvoidmain(String[]args){// 用new创建一个String对象Strings1=newString("hello");// 用new创建另外一个String对象,字符串内容完全相同Strings2=newString("hello");// 证明两个变量是两个对象System.out.println(s1==s2);// false}}字符串在编程中,是最常见的几种对象,因此String方法非常非常丰富。String对象是不可变的,其方法产生的字符串,都是返回一个新的String对象。
String常用的方法
String类的常见方法可以划分为基本操作、转换操作、替换与去除、截取与分隔、判断操作等分类。
String类的基本操作方法有:获取字符串长度、返回字符在字符串中第一次、最后一次出现的索引、返回字符串索引上的字符等。
publicclassDemo2{publicstaticvoidmain(String[]args){Strings1="hello";// 获取字符串的长度System.out.println(s1.length());// 5// 返回字符在字符串中第一次出现的索引System.out.println(s1.indexOf('l'));// 2 (索引从0开始)// 返回字符在字符串中最后一次出现的索引System.out.println(s1.lastIndexOf('l'));// 3// 返回指定索引的字符System.out.println(s1.charAt(1));// e}}String类的转换操作有:将字符串转换为字符数组、将int类型转换为字符串、将字符串中所有字符转换为小写、将字符串中所有字符转换为大写
publicclassDemo3{publicstaticvoidmain(String[]args){Strings1="hello";// 将字符串转换为字符数组char[]chs=s1.toCharArray();for(inti=0;i<chs.length;i++){System.out.print(chs[i]);// hello}System.out.println();// 将int类型转换为字符串inta=10086;Strings2=String.valueOf(a);System.out.println(s2);// 10086// 将字符串中的字符全部转换为大写Strings3=s1.toUpperCase();System.out.println(s3);// HELLO// 将字符串中的字符全部转换为小写Strings4=s1.toLowerCase();System.out.println(s4);// hello}}String类的替换去除操作:用新字符串替换原有字符串,得到一个新的字符串;去除字符串首尾的空格。
publicclassDemo4{publicstaticvoidmain(String[]args){Strings1="hello";// 用新字符串替换原有字符串,得到一个新的字符串Strings2=s1.replace("hello","helloworld");System.out.println(s2);// helloworld// 去除字符串首尾的空格Strings3=" hello ";Strings4=s3.trim();// 建议用strip()替代System.out.println(s4);// hello}}需要注意:
trim()只能去除ASCII码≤32的空白字符(空格、制表符、换行等),但不能去除全角空格或其他Unicode空白字符。Java 11+引入了strip()方法来解决这个问题。因此,建议使用strip()方法替代trim()方法
String类的截取与分隔操作有:根据参数将原字符串分隔为若干个字符串(字符串数组)、截取从指定索引后的所有字符、截取从指定开始索引到指定结束索引之间的字符。
publicclassDemo5{publicstaticvoidmain(String[]args){Strings1="this is a text";// 将原字符串分隔为若干个字符串(字符串数组)String[]arr=s1.split(" ");for(inti=0;i<arr.length;i++){System.out.println(arr[i]);}// 截取从指定索引后的所有字符Strings2="helloworld";System.out.println(s2.substring(5));// world// 截取从指定开始索引到指定结束索引之间的字符System.out.println(s2.substring(2,4));// ll}}String类的判断操作有:判断与指定字符串比较是否相等、判断字符串是否以指定字符串开始、判断字符串是否以指定字符串结尾、判断字符串是否包含指定的字符序列、判断字符串是否为空(字符串长度为0)。
publicclassDemo6{publicstaticvoidmain(String[]args){Strings1="hello";// 判断与指定字符串比较是否相等System.out.println(s1.equals("hello"));// true// 判断字符串是否以指定字符串开始System.out.println(s1.startsWith("he"));// true// 判断字符串是否以指定字符串结尾System.out.println(s1.endsWith("lo"));// true// 判断字符串是否包含指定的字符序列System.out.println(s1.contains("llo"));// true// 判断字符串是否为空System.out.println(s1.isEmpty());// false}}StringBuilder和StringBuffer类
由于String对象是不可变对象,因此String类的所有方法若是返回字符串,都是返回一个新的字符串。由于字符串是高频出现的对象,而因为字符串的不可变特性,对内存的开销较大。
因此,Java系统前后推出了StringBuffer类和StringBuilder类,作为String类的补充。两者都是可变的字符串对象,两者的方法都几乎相同,都是在原字符串上进行变更修改,而不是产生一个新的字符串对象。
以StringBuilder为例,演示StringBuilder和StringBuffer类的常用方法。
publicclassDemo7{publicstaticvoidmain(String[]args){StringBufferstr=newStringBuffer("hello");// append方法:添加字符串str.append(" world");System.out.println(str);// hello world// insert方法:在指定位置添加字符串str.insert(5," java's");System.out.println(str);// hello java's world// replace方法:替换字符串str.replace(5,12," java");System.out.println(str);// hello java world// delete方法:删除字符串str.delete(5,10);System.out.println(str);// hello world}}StringBuffer类和StringBuilder类区别在于相对运行快慢和线程安全性,StringBuffer是线程安全的,运行性能比StringBuilder慢。而StringBuilder虽然是线程不安全的,但是优势在于运行速度快。
packagestring.demo2;publicclassDemo7{publicstaticvoidmain(String[]args){StringBufferstr0=newStringBuffer("hello");StringBuilderstr1=newStringBuilder("hello");// 测试StringBuffer对象方法的运行时间longstart=System.nanoTime();// append方法:添加字符串str0.append(" world");System.out.println(str0);// hello world// insert方法:在指定位置添加字符串str0.insert(5," java's");System.out.println(str0);// hello java's world// replace方法:替换字符串str0.replace(5,12," java");System.out.println(str0);// hello java world// delete方法:删除字符串str0.delete(5,10);System.out.println(str0);// hello worldlongend=System.nanoTime();System.out.println("StringBuffer运行时间:"+(end-start)+"纳秒");System.out.println("------------------------------------------------");// 测试StringBuilder对象方法的运行时间longstart1=System.nanoTime();str1.append(" world");System.out.println(str1);str1.insert(5," java's");System.out.println(str1);str1.replace(5,12," java");System.out.println(str1);str1.delete(5,10);System.out.println(str1);longend1=System.nanoTime();System.out.println("StringBuilder运行时间:"+(end1-start1)+"纳秒");}}hello world hello java's world hello java world hello world StringBuffer运行时间:398609纳秒 ------------------------------------------------ hello world hello java's world hello java world hello world StringBuilder运行时间:92160纳秒 进程已结束,退出代码为0由此可见,StringBuilder确实要更快一些。一般情况下,我们都是单线程运行程序,因此推荐用StringBuilder。