String类
在java中,字符串被作为String
类型的对象处理,即String
是字符串常量的类。
创建String对象
String str = "abc"; //创建一个对象abc,效率高
String str = new String("abc"); //创建两个对象,abc和new出的""对象
String str = new String(); //创建一个空的字符串对象
String类常用方法
以下为String类常用方法,其中一些方法还有多个重载方法,可根据其参数理解方法的具体含义
注意事项:
1.indexOf
和lastIndexOf
方法如果查找不到指定字符/字符串时,返回值为 -1
2.replace()
方法会替换所有匹配的字符,replaceAll()
方法为正则表达式替换
3.split()
方法在使用特殊符号分割时需要进行转义:如*、^、| 转义后(\|),不转义可能报异常或者按""进行分隔
常用方法示例
length()、substring()、charAt()方法
//定义一个字符串"JAVA 编程 基础"
String str="JAVA 编程 基础";
//打印输出字符串的长度:10
System.out.println("字符串的长度是:"+str.length());
//取出字符'程'并输出
System.out.println(str.charAt(6));
//取出子串"编程 基础"并输出
System.out.println(str.substring(5));
//取出子串"编程"并输出
System.out.println(str.substring(5, 7));
indexOf()、lastIndexOf()方法
// 定义一个字符串"JAVA编程基础,我喜欢java编程"
String str=new String("JAVA编程基础,我喜欢java编程");
//查找字符'A'在字符串中第一次出现的位置:1
System.out.println(str.indexOf('A'));
//查找子串"编程"在字符串中第一次出现的位置:4
System.out.println(str.indexOf("编程"));
//查找字符'A'在字符串中最后一次出现的位置:3
System.out.println(str.lastIndexOf('A'));
//查找子串"编程"在字符串中最后一次出现的位置:16
System.out.println(str.lastIndexOf("编程"));
//在字符串index值为8的位置开始,查找子串"编程"第一次出现的位置:16
System.out.println(str.indexOf("编程", 8));
split()、replace()、replaceAll()方法
String str="JAVA 编程 基础";
//将字符串的空格替换成逗号:JAVA,编程,基础
//1.使用split方法对字符串进行分割
String[] arr = str.split(" ");
System.out.println(arr[0] + "," + arr[1] + "," + arr[2]);
//2.使用replace方法进行字符替换
System.out.println(str.replace(" ", ","));
//3.使用replaceAll方法进行字符替换(\\s+表示匹配1或多个空格)
System.out.println(str.replaceAll("\\s+", ","));
//split分割特殊字符:[, AB, C]
System.out.println(Arrays.toString("|AB|C".split("\\|")));
//split分割特殊字符:[A, B, C]
System.out.println(Arrays.toString("A*B*C".split("\\*")));
String与数组
与字节数组的转换
在网络传输、IO流中经常需要对字符串和字节数组进行转换使用。
- 字符串转为byte数组
— 通过getBytes()
或getBytes(Charset charset)
方法
getBytes()
会使用平台的默认字符集将此String编码为byte序列,存储到byte数组中。windows下默认是GBK
getBytes(Charset charset)
使用指定的字符集进行转换,如UTF8、GBK - byte数组转为字符串
— 通过new String(byte[] b)
或new String(byte[] b, Charset charset)
构造方法
// 字符串和byte数组之间的相互转换
//定义一个字符串
String str=new String("JAVA 编程 基础");
//将字符串转换为byte数组,并打印输出
byte[] arrs=str.getBytes("GBK");
for(int i=0;i<arrs.length;i++){
System.out.print(arrs[i]+" ");
}
//打印内容:74 65 86 65 32 -79 -32 -77 -52 32 -69 -7 -76 -95
//其中32是空格的ASCII码值,一个中文两个字节,改为UTF8编码则占用三个字节
System.out.println();
//将byte数组转换为字符串,注意编码需要保持一致
String str1=new String(arrs,"GBK");
System.out.println(str1);
字节是计算机存储信息的基本单位,1字节(byte) = 8位(bit),在UTF8编码下,一个中文是占用了3个字节的,而GBK编码一个中文占用两个字节,中文的字节表示为负数这是因为超出了byte表示的范围而产生了溢出
与字符数组的转换
事实上我们可以将字符串看成是一个字符序列,字符串也有索引的概念,类似数组。
- 字符串转为char数组
— 通过toCharArray()
方法 - char数组转为字符串
— 通过new String(char[] chs)
构造方法
字符串常量池
JVM中有一个字符串常量池,由String类维护,其中保存着很多String对象并且可共享,相同的字符串常量只会存储一个对象。
jdk1.6及之前版本字符串常量池是在方法区中,存放的都是字符串常量。
jdk1.7开始字符串常量池已经转移到堆中了,并且可以存放放于堆内的字符串对象的引用。
分析创建对象方式
分别使用字面值赋值和new方式创建4个相同内容的对象,然后进行比较
//定义四个字符串,内容都是java
String str1="java";
String str2="java";
String str3=new String("java");
String str4=new String("java");
System.out.println("str1和str2的内容相同?"+(str1.equals(str2))); //true
System.out.println("str1和str3的内容相同?"+(str1.equals(str3))); //true
System.out.println("str3和str4的内容相同?"+(str1.equals(str3))); //true
System.out.println("str1和str2的地址相同?"+(str1==str2)); //true
System.out.println("str1和str3的地址相同?"+(str1==str3)); //false
System.out.println("str3和str4的地址相同?"+(str3==str4)); //false
- 执行
String str1 = "java"
时,先去常量池中找是否存在"java",如果存在则直接将"java"的引用赋给str1,如果不存在则先在常量池中新建一个字符串"java",然后再将其引用赋给str1 - 执行语句
String str3=new String("java")
时,也先去常量池中找是否存在"java",存在则不创建新的对象,否则先在常量池中新建一个字符串"java"。然后通过new关键字在堆中创建一个新对象,调用接收String参数的构造器进行初始化,最后将该对象的引用赋值给str3。
内存示意图:
示例
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
//编译时会将常量优化,可以拼在一起的就拼在一起
String s3 = "he" + "llo";
String s4 = "he" + new String("llo");
String s5 = new String("hello");
String s7 = "he";
String s8 = "llo";
//变量参与运算的时候,会生成新的堆内存空间去记录这个值
String s9 = s7 + s8;
System.out.println(s1 == s2);// true
System.out.println(s1 == s3);// true
System.out.println(s1 == s4);// false
System.out.println(s1 == s9);// false
System.out.println(s4 == s5);// false
}
String类的不可变性
String对象一旦被创建,则不能修改,是不可变的
所谓的修改其实是创建了新的对象,所指向的内存空间不变
StringBuilder类
是一个可变的字符序列,类似String的字符串缓冲区,用来临时存储字符串内容的。
StringBuilder与String的区别
String具有不可变性,而StringBuilder不具备。
当频繁操作字符串时,使用StringBuilder效率更高。
StringBuilder与StringBuffer的区别
二者基本类似,StringBuffer是线程安全的,StringBuilder则没有,所以StringBuilder性能略高
创建对象
StringBuilder sb1=new StringBuilder(); //创建空内容的对象
//默认容量16字符(容量不够时会自动扩充)
StringBuilder sb2=new StringBuilder(30);//设置容量30字符
StringBuilder sbf=new StringBuilder("hello"); //初始化内容
常用方法
其中append
和insert
方法能有效的将各种类型参数数据转换成字符串然后将该字符串的字符添加到字符序列中。
示例
// 定义一个字符串"你好"
StringBuilder str=new StringBuilder("你好");
System.out.println(str.length()); //2
System.out.println(str.capacity()); //18
//在"你好"后面添加内容,将字符串变成"你好,World!"
//append后不会创建新的对象,而是修改StringBuilder对象中的内容
System.out.println("str="+str.append(',').append("World!"));
//将字符串变成"你好,WORLD!"
//两种方式:
//1、使用delete方法删除orld,然后在插入ORLD
//System.out.println("替换后:"+str.delete(4, 8).insert(4, "ORLD"));
//2、使用replace方法直接替换
System.out.println("替换后:"+str.replace(4, 8, "ORLD"));
//取出"你好"并输出
System.out.println(str.substring(0,2));
System.out.println(str.length()); //9
网友评论