String类基本概念
- String类属于引用数据类型,不属于基本数据类型。
- 在Java中只要是" "(双引号)中的,都是String对象。
- java中规定,双引号中的字符串是不可变的,也就是说"abc"自出生到死亡都不可能变成"abcd",也不能变成"ab"。
- 在JDK中双引号括起来的字符串都是存储在方法区的字符串常量池当中的。(因为在实际开发中,字符串的使用频率十分高,为了执行效率,就把字符串放在了方法区中的字符串常量池当中)
String字符串的存储原理
- 通过 String s = “abc” 这种方式,会在方法区中的字符串常量池创建对象,s会保存该字符串在字符串常量池中的地址。
- 通过 String s = new String(“abc”)的方式创建对象,首先会在字符串常量池中创建"abc"对象(如果字符串常量池中已经有了"abc"则不会再次创建),然后会在堆区创建String类对象,它会储存" abc "在方法区中的地址,s又会保存堆中String对象的地址。
看以下代码:
public class StringTest01 {
String A = "abc";
String B = "abc" + "de";
String C = new String("abc");
}
按照以上代码画出JVM内存简图如下: 知道了String类字符串的存储原理之后,就可以很容易知道以下代码的编译结果:
public class StringTest01 {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
String m = new String("你好!");
String n = new String("你好!");
System.out.println(s1 == s2);
System.out.println(m == n);
}
}
String类的常用构造方法
public class StringTest02 {
public static void main(String[] args) {
byte []x1 = { 97 , 98 , 99 };
char []x2 = {'我','是','中','国','人'};
String y1 = new String(x1);
System.out.println(y1);
String y2 = new String(x1,1,2);
System.out.println(y2);
String y3 = new String(x2);
System.out.println(y3);
String y4 = new String(x2,2,3);
System.out.println(y4);
}
}
String类中常用方法
public class StringTest03 {
public static void main(String[] args) {
char s1 = "中国人".charAt(1);
System.out.println(s1);
System.out.println("abc".compareTo("abd"));
System.out.println("abc".compareTo("abc"));
System.out.println("abc".compareTo("abb"));
System.out.println("abcdefg".contains("efg"));
System.out.println("abcdefg".contains("hij"));
System.out.println("abcde".endsWith("cde"));
System.out.println("abcde".endsWith("qwe"));
System.out.println("ABcd".equalsIgnoreCase("abCD"));
byte [] s2 = "abcdefg".getBytes();
for (int i = 0; i < s2.length; i++) {
System.out.print(s2[i] + " ");
}
System.out.println("abcdefghigk".indexOf("hig"));
System.out.println("abc".indexOf("fgh"));
System.out.println("abcdhdhdabc".lastIndexOf("abc"));
System.out.println("".isEmpty());
String s3 = "aaatttooo";
System.out.println( s3.replace('t','q'));
String s4 = "abcsgdjsssjabcjdjjdjabc";
System.out.println(s4.replace("abc","www"));
String s5 = "2022-3-19";
String [] str = s5.split("-");
System.out.println(str[0] + str[1] + str[2]);
System.out.println("abcdefgh".substring(4));
System.out.println("abcdefgh".substring(2,5));
char[] str2 = "abcdefg".toCharArray();
for(int i = 0 ; i < str2.length ; i++){
System.out.println(str2[i]);
}
System.out.println("ABcDeFG".toLowerCase());
System.out.println("aCbcdEfg".toUpperCase());
System.out.println(" abcdefg ".trim());
System.out.println(String.valueOf(true));
}
}
StringBuffer类
思考:
- 频繁使用字符串拼接会有什么影响?
- java中字符串是不可变的,每拼接一次都会产生一个新的字符串
- 字符串是存在字符串常量池中的,频繁使用字符串拼接会占用大量的方法区空间
为了避免以上问题我们就可以使用到StringBuffer类
public class StringBufferTest {
public static void main(String[] args) {
StringBuffer strBuffer = new StringBuffer();
strBuffer.append(1);
strBuffer.append('q');
strBuffer.append(3.14);
strBuffer.append("abc");
System.out.println(strBuffer);
StringBuffer newstrBuffer = new StringBuffer(100);
}
}
StringBuilder类
它的用法与StringBuffer十分相似,但是也有很大的区别:
- StringBuffer中的方法都有synchronized关键字修饰,表示StringBuffer在多线程编译环境下是安全的
- StringBuilder中方法没有synchronized关键字修饰,表示StringBuilder在多线程编译环境下是不安全的
|