原文:https://blog.csdn.net/coder_xiaoshun/article/details/122706622?spm=1001.2014.3001.5501
目录:
1. String类概述
1.1 基本概述
-
String 类代表字符串,Java 程序中的所有字符串文字(例如"abcd")都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象。
-
String 类在 java.lang 包下,所以使用的时候不需要导包。
1.2 特点
- String常被称为不可变字符串类型,它的对象在创建后不能被更改。
- String变量每次的修改其实都是指向了产生的新的字符串对象。
- 原来的字符串对象都是放在了堆内存的字符串常量池里,没有改变,所以称不可变字符串。
2. String类创建的方式
2.1 创建字符串的两种方式:
-
直接用 " " 定义;
String name = "张三";
-
通过String类的构造器创建对象。
-
String类常见的构造方法: 方法名 说明 public String() 创建一个空白字符串对象,不含有任何内容 public String(String) 根据传入的字符串内容来创建字符串对象 public String(char[] chs) 根据字符数组的内容来创建字符串对象 public String(byte[] bys) 根据字节数组的内容来创建字符串对象
-
2.2 代码实现创建
public class StringDemo {
public static void main(String[] args) {
// 1.public String() 创建一个空白字符串对象
String s1 = new String();
System.out.println(s1 + "<--这是空的");
// 2.public String(String) 根据 传入的字符串内容 来创建字符串对象
String s2 = new String("天下无贼");
System.out.println(s2);
// 3.public String(char[] chs) 根据 字符数组的内容 来创建字符串对象
char[] arr = {'我','的','名','字','叫','李','四'};
String s3 = new String(arr);
System.out.println(s3);
// 4.public String(byte[] bys)根据 字节数组的内容 来创建字符串对象
byte[] bytes = {97, 98 ,99 , 65, 66, 67}; // 取值范围:-128 -- 127
String s4 = new String(bytes);
System.out.println(s4);
// 5.直接用赋值的方式创建字符串对象
String name = "张三";
System.out.println(name);
}
}
// 输出结果:
<--这是空的
天下无贼
我的名字叫李四
abcABC
张三
2.2.1 两种创建方式的区别
- 以 " " 方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串常量池中维护。
- 通过 new 创建的字符串对象,每一次 new 都会创建一个新内存空间,虽然内容相同,但是地址值不同。
public class StringDemo {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); // true
}
}
public class StringDemo {
public static void main(String[] args) {
char[] chars = {'a', 'b', 'c'};
String s3 = new String(chars);
String s4 = new String(chars);
System.out.println(s3 == s4); // false
}
}
-
补充:
public class StringDemo { public static void main(String[] args) { String s1 = "abc"; String s2 = "a"+"b"+"c"; System.out.println(s1 == s2); // true } }
结果是true。
因为Java存在编译优化的机制,程序在编译
"a"+"b"+"c"
时,会直接转为"abc",所以编译之后s1和s2指向的是同一个地址。
3. 字符串内容的比较
3.1 "=="运算符的作用
-
比较基本数据类型:比较的是具体的值
-
比较引用数据类型:比较的是对象地址值
由此可见字符串内容的比较不适合用“ == ”比较,因为 “ == ” 比较的是字符串在堆内存中的地址。
3.1 equals
Java提供了一款用于比较字符串内容是否一样的API:equals,equals只关心字符串内容是否一样,不会去关系字符串的地址。
方法名 | 说明 |
---|---|
public boolean equals (Object anObject) | 将此字符串与指定对象进行比较,只关心字符内容是否一致。 |
public boolean equalsIgnoreCase (String anotherString) | 将此字符串与指定对象进行比较,忽略比较字符串大小写,只关心字符内容是否一致。 |
-
equals (Object anObject)案例实现:
import java.util.Scanner; public class StringDemo { public static void main(String[] args) { /* 简单模拟用户登陆,进行账号密码比对 */ // 正确的账号密码 String rightID = "zs1234"; String rightPasswd = "123456"; // 用户输入的密码 Scanner input = new Scanner(System.in); System.out.println("请输入登陆用户名:"); String inputID = input.next(); System.out.println("请输入密码:"); String inputPasswd = input.next(); // 使用equals比较 if (rightID.equals(inputID) && rightPasswd.equals(inputPasswd)){ System.out.println("登陆成功"); }else{ System.out.println("账号或密码错误"); } } } // 输出结果: 请输入登陆用户名: zs123 请输入密码: 12345 账号或密码错误 请输入登陆用户名: zs1234 请输入密码: 123456 登陆成功
-
equalsIgnoreCase (String anotherString)案例实现:
public class StringDemo { public static void main(String[] args) { /* equalsIgnoreCase (String anotherString) 通常用于验证码这类不在乎大小写的业务逻辑 */ String rightCdoe = "CaBkl"; String code1 = "cabkl"; System.out.println(rightCdoe.equals(code1)); // false System.out.println(rightCdoe.equalsIgnoreCase(code1)); // true } }
3.3 总结
- 字符串内容的比较应该使用String提供的equals方法。
- 什么时候使用“==”比较数据:
- 比较基本数据类型时使用
- 比较引用数据类型的地址值时使用
4. String类型的常用API
方法名 | 说明 |
---|---|
public int length() | 返回此字符串的长度 |
public char charAt(int index) | 获取某个索引位置处的字符 |
public char[] toCharArray(): | 将当前字符串转换成字符数组返回 |
public String substring(int beginIndex, int endIndex) | 根据开始和结束索引进行截取,得到新的字符串(包前不包后) |
public String substring(int beginIndex) | 从传入的索引处截取,截取到末尾,得到新的字符串 |
public String replace(CharSequence target, CharSequence replacement) | 使用新值,将字符串中的旧值替换,得到新的字符串 |
public boolean contains(CharSequence s) | 判断字符串内容是否包含关键字 |
public boolean startsWiths(String prefix) | 判断字符串是否是以传入的关键字为开始 |
public String[] split(String regex) | 根据传入的规则切割字符串,得到字符串数组返回 |
代码演示:
public class StringDemo {
public static void main(String[] args) {
// 定义一个字符串
String name = "常山赵子龙";
// 1.public int lengt() 返回此字符串的长度
int length = name.length();
System.out.println(length);
// 2.public char charAt(int index) 获取某个索引位置处的字符
char c = name.charAt(2);
System.out.println(c);
// 可以利用此API来遍历字符串中的每个字符
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i)+"\t");
}
System.out.println(" ");
// 3.public char[] toCharArray(): 将当前字符串转换成字符数组
char[] chars = name.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.print(chars[i]+"\t");
}
System.out.println(" ");
// 4.public String substring(int beginIndex, int endIndex)
// 根据开始和结束索引进行截取,得到新的字符串(包前不包后)
String name2 = "会心疼哥哥的张飞";
String rs = name2.substring(1, 5); // 包含开始的索引,不包含结束的(开始的索引, 结束的索引+1)
System.out.println(rs);
// 5.public String substring(int beginIndex) 从传入的索引处截取,截取到末尾
String rs2 = name2.substring(6);
System.out.println(rs2);
// 6.public String replace(CharSequence target,CharSequence replacement)
// 使用新值,将字符串中的旧值替换,得到新的字符串
String name3 = "邢道荣是三国第一战将,貂蝉的老公是邢道荣";
String rs3 = name3.replace("邢道荣", "吕布");
System.out.println(rs3);
// 7.public boolean contains(CharSequence s) 判断字符串内容是否包含传入的关键字
System.out.println(name3.contains("邢道荣")); // true
System.out.println(name3.contains("关羽")); // false
// 8.public boolean startsWiths(String prefix) 判断字符串是否是以传入的关键字为开始
System.out.println(name3.startsWith("邢道荣是三国第一战将")); // true
System.out.println(name3.startsWith("邢道荣是三国第二战将")); // false
System.out.println(name3.startsWith("关羽")); // false
// 9.public String[] split(String regex) 根据传入的规则切割字符串,得到字符串数组返回
String name4 = "中华田园犬,德牧,金毛,拉布拉多,阿拉斯加";
String[] names = name4.split(",");
for (int i = 0; i < names.length; i++) {
System.out.println("邻居家的宠物有:"+names[i]);
}
}
}
输出结果:
5
赵
常 山 赵 子 龙
常 山 赵 子 龙
心疼哥哥
张飞
吕布是三国第一战将,貂蝉的老公是吕布
true
false
true
false
false
邻居家的宠物有:中华田园犬
邻居家的宠物有:德牧
邻居家的宠物有:金毛
邻居家的宠物有:拉布拉多
邻居家的宠物有:阿拉斯加