API文档 => java.lang => String,StringBuilder
String类
创建String对象的方式
String s1 = "song"; // 创建一个字符串对象song,名为s1
String s2 = new String(); // 创建一个空字符串对象,名为s2
String s2 = new String("song"); // 创建一个字符串对象song,名为s3
String对象的常用方法
补充1:String substring(int beginIndex, int endIndex)中,endIndex位置的字符是不会输出的
补充2:方法equels()比较两个字符串内容是否相等,返回值是boolean类型的值
补充3:方法compareTo()比较两个字符串大小,返回值是int的值
字符串与byte数组间的转换
package com.song.test;
public class TryDemoOne {
public static void main(String[] args) {
// 定义一个字符串
String str1 = new String("Java 编程 基础");
// 将字符串装换为byte数组
// getBytes()方法可以有参数,表示字符集
byte[] arrs = str1.getBytes();
for (int i = 0; i < arrs.length; i++) {
System.out.print(arrs[i] + " ");
}
System.out.println();
// 将byte数组装换为字符串
// new String(arrs)可以有第二个参数,表示字符集
// 注意字符集要一致,否则无法正常转换
String str2 = new String(arrs);
System.out.println(str2);
}
}
等于运算符与equals方法
package com.song.test;
public class TryDemoOne {
public static void main(String[] args) {
String str1 = "imooc";
String str2 = "imooc";
String str3 = new String("imooc");
System.out.println("str1与str2的内容相同?" + str1.equals(str2)); // true
System.out.println("str1与str3的内容相同?" + str1.equals(str3)); // true
System.out.println("str1与str2的地址相同?" + (str1 == str2)); // true
System.out.println("str1与str3的地址相同?" + (str1 == str3)); // false
}
}
字符串的不可变性
例子1:
package com.song.test;
public class TryDemoOne {
public static void main(String[] args) {
// String对象一旦被创建,则不能修改,是不可变的
// String对象指向常量池的字符串,而常量池中的内容是不可修改的
// 所谓的字符串修改其实是创建了新的对象,该新对象指向常量池中的"hello song"常量
// 只不过新的对象与原对象所在的地址是一样的,相当于覆盖了原对象
String s1 = "imooc";
s1 = "hello " + s1;
System.out.println(s1); // hello imooc
}
}
例子2:
package com.song.test;
public class TryDemoOne {
public static void main(String[] args) {
String s1 = "imooc";
String s2 = "hello " + s1;
System.out.println(s1); // imooc
System.out.println(s2); // hello imooc
}
}
StringBuilder类
StringBuilder概述
String和StringBuilder
- String具有不可变性
- StringBuilder不具备
StringBuilder和StringBuffer
- 二者基本相似,也就是说这两个类的方法基本是一致的
- StringBuffer是线程安全的,StringBuilder则没有,所以性能略高
为什么有安全的类不用,去用不安全的类呢?首先,线程安全主要是针对多线程的。而大部分情况下,我们在做字符串处理的时候,都是单线程的,所以用StringBuilder就可以了。
建议:
当频繁操作字符串时,使用StringBuilder。因为String具有不可变性,所以当用String频繁操作字符串的时候,会产生很多中间变量和废弃常量,而StringBuilder可以避免这种情况的发生。
_
StringBuilder常用方法
package com.song.test;
public class TryDemoOne {
public static void main(String[] args) {
// 定义一个字符串"你好"
StringBuilder str = new StringBuilder("你好");
// 在"你好"后面添加内容,将字符串变成"你好,song"
str = str.append(",song");
System.out.println(str);
// 将字符串变成"你好,SONG"
str = str.delete(3, 7).insert(3, "SONG");
System.out.println(str);
// 将字符串变成"你好,NIAN"
str = str.replace(3, 7, "NIAN");
System.out.println(str);
// 在字符串中取出"你好"
System.out.println(str.substring(0, 2));
}
}
知识巩固
案例1:
输出结果:false true
结果分析:
执行Integer x=400;这段代码会创建一个Integer对象,x的引用指向它;执行Integer y = x;这段代码,y的引用和x的引用指向了同一片内存空间。这时,x和y指向同一个对象。之后,执行x++,将会创建一个新的Integer对象401,然后x的引用指向新创建的对象。这时x和y不再指向同一个对象。执行x==y得到结果为false;
执行StringBuilder sb1 = new StringBuilder(“123”);这段代码时,在堆中生成一个StringBulider对 象,内容为:123,这时有一个sb1的引用指向”123”这个内容。执行StringBuilder sb2 = sb1;这段代 码,sb2的引用同样指向”123”这个内容。在执行sb1.append(“5”);时,会在内存中”123”这个位置变成 了”1235”,这时没有在内存当中生成新的对象,也没有新的字符串常量,而是在原来的基础上进行了修 改。sb1和sb2指向的是同一个对象,所以执行sb1==sb2得到结果为true。
案例2:写出下列代码的输出结果
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = "abc"+"def";
String s4 = "abcdef";
String s5 = s2+"def";
String s6 = new String("abc");
System.out.println(s1==s2); // true
// "abc"字符串是放在内存中的常量池里的,== 比较的是内存地址,所以这里的结果是true
System.out.println(s3==s4); // true
// s3的结果是字符串"abcdef",也是存放在内存中的常量池里的,所有这里的结果也是true
System.out.println(s4==s5); // false
// s5里的s2是变量,在程序编译阶段无法知道数值,在s2+"def"之后会产生一个新的内存地址
// 然后分配给s5,所以这里s4和s5是不一致的,结果为false
System.out.println(s4.equals(s5)); // true
// equals比较的是字符串是否一致,所以结果为true
System.out.println(s1==s6); // false
// new String("abc")创建一个字符串对象,是不会在常量池中保存的,所以结果是false
}
案例3:String,String Builder 和 StringBuffer的区别