Java学习笔记——String类

String类

1.字符串对象

Java中的字符串属于对象,Java提供了 String 类来创建和操作字符串
String 类可被 final 修饰,但不能被继承重写

(1).字面量
含义:直接写出来的数值

10 -> int 字面量
10.1 -> double 字面量
true -> boolean 字面量
“abc” -> String 字面量 -> 就是一个字符串对象

(2).创建字符串的四种方式

方法一:直接赋值

String str = "Bye 2022!";

方法二:通过构造方法产生对象

Sring str2 = new String("Hello 2023!");

方法三:通过字符串数组产生对象

char[] data = new char[] {'a' , 'b' , 'c'};
String str = new String(data);

方法四:通过 String 静态方法 valuesOf (任意数据类型) -> 转换为字符串

String str = String.valueOf(10);
2.字符串常量池

1.使用 String 创建字符串对象后,JVM 会维护一个字符串常量池,若该对象不存在,则产生一个新的字符串对象,并加入到字符串常量池中。

2.继续使用赋值法产生字符串对象时,JVM 发现该引用指向内容在常量池中已经存在,则此时不再新建字符串对象,而是复用已有对象

String a = "1"; // 常量池加入 "1"
String b = a + a; // JVM 优化为 "11"
b.intern();
//intern: 若该对象在常量池中不存在,则将该对象加入常量池,且将引用 "b" 指向常量池内的 "11"
String c = "11"; // 指向常量池
String d = new String("11"); // 堆中开辟新的空间 "11",常量池字符串与堆中的普通字符串永远不相等
String d1 = d.intern; // 该对象常量池中存在,引用 "d1" 指向常量池内的 "11"

System.out.println(b == c); // true
System.out.println(d == c);	// false
System.out.println(d1 == c); // true
System.out.println(d1 == d); // false

图示:
常量池代码图示

注:
(1).直接使用双引号声明的 String 对象会储存在常量池

(2).String 对象的 intern 方法会得到字符串在常量池对应的引用,如果常量池中没有对应字符串,则该对象会被添加到常量池

3. intern 关键字

1.若当前常量池中已经存在该对象,则不会产生新的对象,返回常量池中的 String 对象
2.若当前常量池中不存在该对象,则将该对象入池,返回池后地址
3.对于任意两个字符串 st ,当且仅当s.equals(t)true 时,s.intern() == t.intern() 才为 true

语法:

public native String intern();

值得注意的是:intern 关键字直接打印输出没有什么效果,但其作用往往在 == 比较字符串常量池地址时显现。

// 这个 new "猫咪" 的猫咪不入常量池
String a = new String("猫咪"); 
String b = new String("猫咪");
String c = "猫咪";
String d = "猫" + "咪";
String e = "咪";
String f = "猫" + e;

System.out.println(a.intern() == b); // false
System.out.println(a.intern() == c); // true
System.out.println(a.intern() == d); // true
System.out.println(a.intern() == f); // false
System.out.println(a.intern() == b.intern()); // true

代码图示
intern 代码图示

4.字符串的比较

(1).所有引用数据类型在比较是否相等时,使用equals方法比较
(2).引用数据类型使用 == 比较的是数值(地址是否相等)
(3).区分大小比较 .equals ,不区分大小写比较 .equalsIgnorCase
(4).延伸:用户输入判空处理

System.out.println(useName.equals("三三")); // ×,最好不要这样做
System.out.println("三三".equals(useName)); // √,要把比较的内容放在前面,避免输入值为空
5.扩展:匿名对象

(1).匿名对象:new Student();

匿名对象的创建只存在于堆中,没有名字,只能使用一次

(2).非匿名对象:Student stu = new Student();

非匿名对象创建的对象也存在于堆中,但其类变量却在栈中,栈中的类变量通过创建变量的内存地址指向相应的对象

6.字符串的不可变性

1.字符串对象的内容不可变,字符串引用可以改变

2.字符串其实就是一个字符数组 -> char[] ,字符串保存的值实际上在数组中保存。

3.char[] 在源码中被 final 修饰,权限为 private ,String 类的外部拿不到这个 value 数组 private final char value[];

4.运行时通过反射 (field) 破坏value 数组的封装 (private) 可以进行修改

7.常用方法

构建与修改字符串对象

类名用法描述*
StringBuilder()拼接字符串非线程安全,性能较好
StringBuffer()拼接字符串线程安全,性能较差
sb.reverse()反转字符串
sb.delete(int start,int end)删除指定范围的数据
sb.insert(int start,[all])将新元素插入当前sb对象
(用到时补充)…

常用关键字

关键字用法
str.charAt(“i”)将第 i 位字符转换为 char 类型
str.isEmpty()判断是否为空字符串
str.getBytes()按照GBK编码将字符串转换为字节数组
str.split(“c”,拆分长度)拆分字符串
str.replaceAll(“c”,“替换符号”)替换原字符串
str.replaceFirst(“c”,“替换符号”)替换第一个遇到的字符"c"
str.trim()去除两边空格,保留中间位置空格
str.contanis(“c”)是否包含“c”
str.startWith(“c”)初始字符是否为"c"
str.endWith(“c”)结尾字符是否为"c"
str.toUpperCase()转大写
str.toLowerCase()转小写
(用到时补充)…

注:
(1).String 是不可变字符序列,StringBuilder 和 StringBuffer 是可变字符序列

(2).执行速度StringBuilder > StringBuffer > String

(3).StringBuilder是非线程安全的,StringBuffer 是线程安全的

8.附加练习

一、判断字符串是否是纯数字

public boolean isNumber(String str) {
	// 转换为字符串数组
	char[] data = str.toCharArray();
	// 遍历循环
	for (char c : data) {
		// 判断是否是纯数字,找反例
		// if (c < '0' || c > '9') {
		//.isDigit() 如果字符为数字则返回 true
		if (!Character.isDigit(c)) {
			return false;
		}
	}
	return true;
}

二、单词首字母大写操作

public String firstUpper(String str) {
	// 判空
	if (str == null || str.isEmpty()) {
		return null;
	}
	// 边界条件
	if (str.length() == 1) {
		return str.toLowerCase();
	}
	// 截取 str 最大长度 1 ,截取首位大写 + 截取后半部分拼接
	return str.substring(0,1).toUpperCase() + str.substring(1);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值