java.lang.String类的使用
- 概述
String:字符串,使用一对""引起来表示。
1.String声明为final的,不可被继承
2.String实现了Serializable接口:表示字符串是支持序列化的。
实现了Comparable接口:表示String可以比较大小。
3.String内部定义了final char[] value用于存储字符串数据
4.通过字面量的方式给一个字符串赋值,此时的字符串值声明在字符串常量池中。
5.字符串常量池中是不会存储相同内容(使用String类的equals()比较,返回true)的字符串的。 - String的不可变性
String:代表不可变的字符序列。简称:不可变性。
说明:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。
2.当对现有的字符串进行连续操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
3.当调用String的replace()方法修改指定的字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
代码举例
String s1 = "abc";//字面量的定义放式
String s2 = "abc";
s1 = "hello";
System.out.println(s1 == s2);//比较s1和s2的地址值
System.out.println(s1);//hello
System.out.println(s2);//abc
System.out.println("**********************");
String s3 = "abc";
s3 += "def";
System.out.println(s3);//abcdef
System.out.println(s2);
System.out.println("**********************");
String s4 = "abc";
String s5 = s4.replace('a', 'm');
System.out.println(s4);//abc
System.out.println(s5);//mbc
- String实例化的不同方式
3.1 方式说明
String的实例化方式:
方式一:通过字面量定义的方式
方式二:通过new + 构造器的方式
3.2 代码举例
//通过字面量定义的方式:此时的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
3.3 面试题
面试题:String s = new String(“abc”);方式创建对象,在内存中创建了几个对象?
两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:“abc”
3.4 图示
- 字符串拼接方式赋值的对比
4.1 说明
1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
2.只要其中有一个是变量,结果就在堆中。
3.如果拼接的结果调用intern()方法,返回值就在常量池中。
4.2 代码举例
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(s5 == s6);//false
System.out.println(s3 == s7);//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 s1 = "javaEEhadoop";
String s2 = "javaEE";
String s3 = s2 + "hadoop";
System.out.println(s1 == s3);//false
final String s4 = "javaEE";//s4:常量
String s5 = s4 + "hadoop";
System.out.println(s1 == s5);//true
- 常用方法
String str1 = "聚光科技堆空间聚";
String str2 = str1.replace('聚', '懂');
System.out.println(str1);
System.out.println(str2);
String str3 = str1.replace("聚光", "手打");
System.out.println(str3);
String str1 = "helloworld";
boolean b1 = str1.endsWith("ld");
System.out.println(b1);
boolean b2 = str1.startsWith("He");
System.out.println(b2);
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);
String str2 = "wo";
System.out.println(str1.contains(str2));
System.out.println(str1.indexOf("lo"));
System.out.println(str1.indexOf("lo",5));
String str3 = "hellorworld";
System.out.println(str3.lastIndexOf("or"));
System.out.println(str3.lastIndexOf("or",6));
//什么情况下,indexOf(str)和lastIndexOf()返回值相同?
//情况一:存在唯一的一个str。 情况二:不存在str
String s1 = "HelloWorld";
String s2 = "helloworld";
System.out.println(s1.equals(s2));
System.out.println(s1.equalsIgnoreCase(s2));
String s3 = "abc";
String s4 = s3.concat("def");
System.out.println(s4);
String s5 = "abc";
String s6 = new String("abc");
System.out.println(s5.compareTo(s6));//涉及到字符串排序
String s7 = "打算的订单";
String s8 = s7.substring(2);
System.out.println(s7);
System.out.println(s8);
String s9 = s7.substring(2, 4);
System.out.println(s9);
String s1 = "HelloWorld";
System.out.println(s1.length());
System.out.println(s1.charAt(0));
System.out.println(s1.charAt(9));
// System.out.println(s1.charAt(10));
// s1 = "";
System.out.println(s1.isEmpty());
String s2 = s1.toLowerCase();
System.out.println(s1);//s1不可变的,仍为原来的字符
System.out.println(s2);//改成小写以后的字符串
String s3 = " he llo world ";
String s4 = s3.trim();
System.out.println("--------" + s3);
System.out.println("--------" + s4);
- String与其它结构的转换
6.1 与基本数据类型、包装类之间的转换
String --> 基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)
基本数据类型、包装类 --> String:调用String重载的valueOf(xxx)
String str1 = "123";
int num = Integer.parseInt(str1);
String str2 = String.valueOf(num);
String str3 = num + "";
System.out.println(str1 == str3);
6.2 与字符数组之间的转换
String --> char[]:调用String的toCharArray()
char[] --> String:调用String的构造器
String str1 = "abc123";
char[] charArray = str1.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);
6.3 与字节数组之间的转换
String --> byte[]:调用String的getBytes()
byte[] --> String:调用String的构造器
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则出现乱码
String str1 = "abc123总和";
byte[] bytes = str1.getBytes();//使用默认的字符集,进行转换
System.out.println(Arrays.toString(bytes));
byte[] gbks = str1.getBytes("gbk");//使用gbk字符集,进行编码
System.out.println(Arrays.toString(gbks));
System.out.println("*********************");
String str2 = new String(bytes);//使用默认的字符集,进行解码
System.out.println(str2);
6.4 与StringBuffer、StringBuilder之间的转换
String --> StringBuffer、StringBuilder:调用StringBuffer、StringBuilder构造器
StringBuffer、StringBuilder --> String:①调用String构造器②StringBuffer、StringBuilder的toString()
- JVM中字符串常量池存放位置说明:
jdk 1.6:字符串常量池存储在方法区(永久区)
jdk 1.7:字符串常量池存储在堆空间
jdk 1.8:字符串常量池存储在方法区(元空间)