【Java常用类之String类18】
一、String类
1、JDK自带的字符串类型
2、String类型的字符串对象,一旦创建不可改变,因为String底层采用的是"private final char value[];",abc字符串只能是abc,不能是abcd或者ab
3、JDK对字符串类型做了一些特殊的处理
因为字符串使用的频率太高,为了提高字符串对象访问效率,引入了“字符串常量池”。字符串常量池在方法区中。
字符串常量池在方法区中,字符串常量池其实就是一个“缓存”(缓存是提高程序执行效率的重要手段)
4、字符串对象的访问原理:
在Java程序中一旦遇到“双引号”,就会在字符串的方法区常量中去搜索该字符串对象,,如果搜索到的话就直接使用,如果搜索不到的话直接在字符串常量池中创建一个。
堆区中是运行期分配的,常量池中是编译器分配的。
引用放栈区,对象放堆区,常量放方法区
例一:
package com.JavaStudy.wrapperString0617; /** * @Author wufq * @Date 2020/6/17 14:45 */ public class StringTest01 { public static void main(String[] args){ String s1 = "abc";//s1指向方法区字符串常量中的abc对象 s1 = "def"; //s1指向方法区字符串常量中的def对象 System.out.println(s1); //def --->从上面可以看出String指向对象不能改变,但是值是可以被修改的 //方法去中保存了三个String类型的对象:分别是hello,world和helloworld! String s2 = "hello"+"world!"; System.out.println(s2); //helloworld! } }
例2:
package com.JavaStudy.wrapperString0617; /** * @Author wufq * @Date 2020/6/17 15:52 */ public class StringTest02 { public static void main(String[] args){ //不同的引用指向同一个字符串常量,内存地址是相同的 String s1 = "hello"; String s2 = "hello"; System.out.println(s1==s2);//true //采用new关键字创建的String字符串,会在方法区中保存一个内存地址,堆区中保存两个内存地址 String s3 = new String("ABC"); String s4 = new String("ABC"); System.out.println(s3==s4); //false //比较两个字符串的值是否一样,必须使用equals方法 //String类已经重写了Object类里面的equals方法(即:覆盖了Object的),比较的不是内存地址,而是字符串内容 System.out.println(s3.equals(s4));//true //String类重写了toString方法,获取的字符串本身的内容 System.out.println(s3.toString()); } }
二、关于字符串对象的构造
package com.JavaStudy.wrapperString0617; /** * @Author wufq * @Date 2020/6/17 16:42 * 字符串对象的构造 */ public class StringTest03 { public static void main(String[] args){ //第一种 String s1 = "abc"; //第二种 String s2 = new String ("abc"); //第三种:把byte类型的数组转换成字符串 byte[] bytes = {97,98,99};//a b c 在ASII中的值就是97,98,99 String s3 = new String(bytes); //第四种:把byte类型的数组其中的几个数据转换成字符串 String s4 = new String(bytes,1,2);//1代表的是从第几个开始,2代表的是长度,即从byte1数组的第一个数开始,一共取两个 //第五种:把char类型的数据转换成字符串 char[] chars = {'a','b','c'}; String s5 = new String(chars); //第六种:把chars类型的数组其中的几个数据转换成字符串 String s6 = new String(chars,1,2); System.out.println(s1); System.out.println(s2); System.out.println(s3); System.out.println(s4); System.out.println(s5); System.out.println(s6); } } =====执行结果===== abc abc abc bc abc bc
三、String的常用方法
endWith:判断字符串是否以指定的后缀结束
statrtWith:判断字符串是否以指定的前缀开始
equals:字符串相等比较,不忽略大小写
equalsIgnoreCase:字符串相等比较,忽略大小写
index0f:取的制定字符在字符串的位置
lastIndex0f:返回最后一次字符串出现的位置
length:取得字符串的长度
replaceAll:替换字符串指定的内容
split:根据指定的表达式拆分字符串
substring:截子串
trim:去首尾空格
valus0f:将其他类型转换成字符串
package com.JavaStudy.wrapperString0617; /** String常用方法 */ public class StringTest04 { public static void main(String[] args){ //char charAt(int index ) -->返回指定索引处的 char 值。 String s1 = "钓鱼岛是中国的"; char c1 = s1.charAt(4); System.out.println("c1 = "+c1); //boolean contains (CharSequence s) -->判断字符串内是否包含指定的char值,包含为true不包含为false String s2 = "/ert/login?username=test&passwd=test"; System.out.println("s2 = "+s2.contains("?")); //boolean endsWith(String suffix) -->判断字符串是否以指定的字符串结束 String s3 = "www.baidu.com"; System.out.println("s3 = "+s3.endsWith(".com")); //boolean startsWith(String suffix) -->判断字符串是否以指定的字符串开始 String s4 = "www.baidu.com"; System.out.println("s4 = "+s4.startsWith("www")); //boolean equals(Object anObject) --> 字符串中的数据做比较 String s5 = "abc"; System.out.println("s5 = "+s5.equals("abc")); //boolean equalsIgnoreCase(String anotherString) -->判断两个字符串是否相等,忽略大小写 String s6 = "ABC"; System.out.println("s6 = "+s6.equalsIgnoreCase("abc")); //byte[] getBytes() -->使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 String s7 = "abc"; byte[] bytes = s7.getBytes(); for(int i=0;i<bytes.length;i++){ System.out.print("bytes["+i+"]="+bytes[i]+"\t"); } //int indexOf(String ch) -->返回指定子字符串在此字符串中第一次出现处的索引。 String s8 = "www.test.com.cn"; int index = s8.indexOf("t"); System.out.println("\ns8 = "+index); // int length() -->返回字符串长度 String s9 = "www.test.com.cn"; System.out.println("s9 = "+s9.length()); // String replace(char oldChar, char newChar) -->用 newChar 替换所有 oldChar String s10 = "a2a2"; String r1 = s10.replace('2','A'); System.out.println("r1 = "+r1); //String[] split(String regex) -->字符拆分为字符数组 String s11 = "2020,06,18"; String[] splits = s11.split(","); for(int i=0;i<splits.length;i++){ System.out.print("splits["+i+"] = "+splits[i]+"\t"); } //String substring(int beginIndex) -->从原字符串中取子字符串 String s12 = "/rep/login?user=admin&passwd=123"; String sub = s12.substring(6); System.out.println("\ns12 = "+sub); //String substring(int beginIndex, int endIndex)-->从原字符串中取子字符串,两个形式参数代表,开始下标,结束下标 String s13 = "/rep/login?user=admin&passwd=123"; String sub1 = s13.substring(6,13); System.out.println("s13 = "+sub1); //char[] toCharArray() -->将此字符串转换为一个新的字符数组。 String s14 = "ABCD"; char[] toCharArray = s14.toCharArray(); for(int i=0;i<toCharArray.length;i++){ System.out.print("toCharArray["+i+"] = "+toCharArray[i]+"\t"); } //String toLowerCase() -->将此 String 中的所有字符都转换为小写 String s15 = "ABCDE"; System.out.println("\ns15 = "+s15.toLowerCase()); //String toUpperCase()-->将此 String 中的所有字符都转换为大写 String s16 = "abcde"; System.out.println("s16 = "+s16.toUpperCase()); //String trim(); -->返回字符串的副本,忽略收尾空格。 String s17 = " a bc "; System.out.println("s17 = "+s17.trim()); //String valueOf(int i) -->返回 int 参数的字符串表示形式。 int s18 = 123; System.out.println("s18 = "+String.valueOf(s18)); } } ====执行结果==== c1 = 中 s2 = true s3 = true s4 = true s5 = true s6 = true bytes[0]=97 bytes[1]=98 bytes[2]=99 s8 = 4 s9 = 15 r1 = aAaA splits[0] = 2020 splits[1] = 06 splits[2] = 18 s12 = ogin?user=admin&passwd=123 s13 = ogin?us toCharArray[0] = A toCharArray[1] = B toCharArray[2] = C toCharArray[3] = D s15 = abcde s16 = ABCDE a bc s18 = 123
四、字符串的拼接
1、StringBuffer类
|-- StringBuffer是可变长度字符串
|-- StringBuffer在多线程的环境下是安全的(StringBuffer是线程同步的)
举例说明:不使用和使用StringBuffer拼接字符串的效率
package com.JavaStudy.wrapperString0617; /** * @Author wufq * @Date 2020/6/18 16:52 * 字符串的拼接-->StringBuffer */ public class StringTest05 { public static void main(String[] args){ //不使用StringBuffer的拼接耗时 String s1 = "china"; String s2 = "flight!"; long stime = System.currentTimeMillis(); for(int i=0;i<5000;i++){ s1 = s1+s2; } long etime = System.currentTimeMillis(); System.out.println(etime-stime);//243ms } }
package com.JavaStudy.wrapperString0617; /** * @Author wufq * @Date 2020/6/18 16:55 */ public class StringTese06 { public static void main(String[] args){ //使用StringBuffer的拼接耗时 StringBuffer s1 = new StringBuffer("world"); StringBuffer s2 = new StringBuffer("china"); long stime = System.currentTimeMillis(); for(int i=0;i<5000;i++){ s1.append(s2); //append方法是在s1后面追加s2 } long etime = System.currentTimeMillis(); System.out.println(etime-stime);//1ms } }
2、StringBuffer类中的append方法-->append方法被重写了,可以追加各种类型的数据
package com.JavaStudy.wrapperString0617; /** * @Author wufq * @Date 2020/6/18 17:12 */ public class StringTest07 { public static void main(String[] args){ StringBuffer sBuffer = new StringBuffer(); sBuffer.append(1); sBuffer.append('e'); sBuffer.append(1.2f); sBuffer.append(1.2); sBuffer.append(3l); sBuffer.append(true); sBuffer.append("word"); System.out.println(sBuffer);//1e1.21.23trueword //数组转换字符串 StringBuffer interest = new StringBuffer(); String[] data = {"旅游","美食","健身","睡觉"}; for(int i=0;i<data.length;i++){ //if判断的作用是避免最后一个数加逗号 if(i==data.length-1){ interest.append(data[i]); }else { interest.append(data[i]); interest.append(","); } } System.out.println(interest);//旅游,美食,健身,睡觉 } }
3、正则表达式
初步认识:
1、正则表达式是一门独立的学科,和Java没有关系,只是在Java的String类可以使用
2、正则表达式是一个字符模式,该正则表达式和字符串进行匹配(专门做字符串匹配的)
常用的正则:
QQ号匹配
EMAIL正则
。。。
正则中的一些相关特殊符号:
a{2} 等同于“aa”
\d 代表所有的数字
\D 代表所有的非数字
\w代表所有的英文字母
\W代表所有的非英文字母
package com.JavaStudy.wrapperString0617; /** * @Author wufq * @Date 2020/6/18 17:44 */ public class StringTest08 { public static void main(String[] args){ String s1 = "aa"; boolean b = s1.matches("a{2}"); //matches匹配的意思 System.out.println(b); String s2 = "aaaaa22222bcf34hhhhhh8888"; System.out.println(s2.replaceAll("aa","中")); //将aa提替换为中 System.out.println(s2.replaceAll("a{2}","中")); //将数字提替换为中 System.out.println(s2.replaceAll("\\d","中")); //将非数字提替换为中 System.out.println(s2.replaceAll("\\D","中")); } }