介绍:应用程序编程接口。在 Java 中,API 指的是 JDK 提供的各种功能类,这些类把底层实现封装好了,我们不用关心内部怎么写的,直接用就行
用 API 帮助文档步骤:以查Random
类为例
打开帮助文档,找到索引输入框
输入 “Random”,按回车
看类在哪个包(java.util
包,用的时候要导包)
看类的描述(知道它是生成随机数的)
看构造方法(比如new Random()
创建对象)
看成员方法(比如nextInt()
生成整数随机数)
例子:
import java.util.Random;
public class APIDemo {
public static void main(String[] args) {
Random r = new Random(); // 创建Random对象
int num = r.nextInt(10); // 生成0-9的随机数
System.out.println("随机数:" + num);
}
}
介绍:String 类代表字符串,Java 里所有双引号括起来的都是 String 对象
String 类的特点:
字符串不可变:创建后内容不能改比如String s = "a"; s = "b";
,其实是重新创建了 “b” 对象,“a” 还在内存里,只是 s 不再指向它
字符串可共享:如果内容相同,只会存一份比如String s1 = "abc"; String s2 = "abc";
,s1 和 s2 指向同一个 “abc” 对象
底层是字节数组:表面像字符数组char[]
,实际存的是byte[]
,存的是字符的 ASCII 码值
String 类的构造方法
方法名 | 说明 |
---|---|
public String() | 创建空字符串,如new String()结果是 “” |
public String(char[] chs) | 用字符数组创建字符串,如char[] ch = {‘a’,‘b’}; new String(ch)结果是 “ab” |
public String(byte[] bys) | 用字节数组创建字符串,如byte[] b = {97,98}; new String(b)结果是 “ab”(97 是 ‘a’ 的 ASCII 码) |
String s = “abc”; | 直接赋值创建,最常用,如String s = “hello”; |
例子:
public class StringDemo {
public static void main(String[] args) {
// 空字符串
String s1 = new String();
System.out.println("s1长度:" + s1.length()); // 0
// 字符数组创建
char[] ch = {'h', 'e', 'l'};
String s2 = new String(ch);
System.out.println("s2:" + s2); // hel
// 字节数组创建
byte[] b = {100, 101}; // 'd'和'e'的ASCII码
String s3 = new String(b);
System.out.println("s3:" + s3); // de
// 直接赋值
String s4 = "world";
System.out.println("s4:" + s4); // world
}
}
创建字符串对象两种方式的区别:
构造方法(new):每次new
都会在堆里新建对象,地址不同比如String s1 = new String("a"); String s2 = new String("a");
,s1 和 s2 地址不同。
直接赋值(“”):内容相同的字符串只存一份在字符串常量池,地址相同比如String s1 = "a"; String s2 = "a";
,s1 和 s2 指向同一个 “a”
字符串的比较:
== 号:
基本数据类型:比数值,如int a=1; int b=1; a==b
是true
引用数据类型(如 String):比地址值,如new String("a") == new String("a")
是false
,因为地址不同
equals 方法:专门比字符串内容,忽略地址,区分大小写。如"a".equals("A")
是false
,"a".equals("a")
是true
例子:
public class StringCompareDemo {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("abc");
String s3 = "abc";
String s4 = "abc";
// ==比较地址
System.out.println(s1 == s2); // false(new出来的地址不同)
System.out.println(s1 == s3); // false(一个在堆,一个在常量池)
System.out.println(s3 == s4); // true(都在常量池,地址相同)
// equals比较内容
System.out.println(s1.equals(s2)); // true(内容都是abc)
System.out.println(s3.equals("abc")); // true
}
}
字符串常用方法:
方法名 | 说明 |
---|---|
length() | 求字符串长度,如"abc".length()是 3 |
charAt(int index) | 取指定索引的字符,索引从 0 开始,如"abc".charAt(1)是 ‘b’ |
substring(int begin, int end) | 截取子字符串,含 begin,不含 end,如"abcde".substring(1,3)是 “bc” |
replace(CharSequence target, CharSequence replacement) | 替换字符串,如"abc".replace(“a”, “x”)是 “xbc” |
split(String regex) | 按规则分割字符串,返回字符串数组,如"a,b,c".split(“,”)得到[“a”,“b”,“c”] |
代码验证(替换和分割):
public class StringMethodDemo {
public static void main(String[] args) {
// 替换敏感词
String str = "你好TMD,这是GDX";
String newStr = str.replace("TMD", "***").replace("GDX", "***");
System.out.println(newStr); // 你好***,这是***
// 分割手机号
String phone = "138-1234-5678";
String[] arr = phone.split("-");
for (String s : arr) {
System.out.println(s); // 138 1234 5678
}
}
}
介绍:一个可变的字符串容器,专门用来高效拼接和反转字符串。比如拼接多个字符串时,用它比 String 效率高很多,因为 String 每次拼接都会生成新对象,而它直接在原有容器里改
基本用法:
创建对象:
StringBuilder sb = new StringBuilder();
空容器
StringBuilder sb = new StringBuilder("初始内容");
带初始值,如new StringBuilder("abc")
常用方法:
append(内容)
:添加内容,支持各种类型(字符串、数字、布尔等),如sb.append("x").append(123)
reverse()
:反转字符串,如sb.reverse()
把 “abc” 变成 “cba”
toString()
:转成 String 对象,如String str = sb.toString();
代码验证(拼接和反转):
public class StringBuilderDemo {
public static void main(String[] args) {
// 拼接字符串
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" ").append("World");
System.out.println(sb); // Hello World
// 反转字符串
sb.reverse();
System.out.println(sb); // dlroW olleH
// 转成String
String str = sb.toString();
System.out.println("转成String:" + str); // dlroW olleH
}
}
链式编程:方法可以连续调用,比如sb.append("a").append("b").reverse();
,代码更简洁
例子:
String result = new StringBuilder()
.append("开始")
.append("拼接")
.append("多个")
.append("内容")
.reverse() // 反转整个字符串
.toString();
System.out.println(result); // 容内个多接拼始开
介绍:和 StringBuilder 类似,也是可变字符串容器,但更适合按固定格式拼接字符串,比如用指定分隔符连接多个元素,或者添加首尾符号
基本用法:
创建对象并指定分隔符:StringJoiner sj = new StringJoiner("分隔符");
如new StringJoiner(",")
,元素用 “,” 分隔
带首尾符号的创建:StringJoiner sj = new StringJoiner("分隔符","前缀","后缀");
如new StringJoiner(",", "[", "]")
,结果像[a, b, c]
添加元素:用add("元素")
添加,如sj.add("a").add("b")
代码验证:
import java.util.StringJoiner;
public class StringJoinerDemo {
public static void main(String[] args) {
// 普通用法(用“, ”分隔)
StringJoiner sj1 = new StringJoiner(", ");
sj1.add("苹果").add("香蕉").add("橘子");
System.out.println(sj1); // 苹果, 香蕉, 橘子
// 带首尾符号([ ]包裹,用“, ”分隔)
StringJoiner sj2 = new StringJoiner(", ", "[", "]");
sj2.add("周一").add("周二").add("周三");
System.out.println(sj2); // [周一, 周二, 周三]
// 转成String
String str = sj2.toString();
System.out.println("转成String:" + str); // [周一, 周二, 周三]
}
}
字符串存储位置:
直接赋值(如String s = "abc";
):“abc” 存在字符串常量池(JVM 的一块特殊内存区域),如果常量池里已有 “abc”,s 直接指向它,不会新建
new 创建(如String s = new String("abc");
):
先检查常量池有没有 “abc”,没有就先创建到常量池
然后在堆内存里新建一个 String 对象,指向常量池的 “abc”
所以s1 = new String("a"); s2 = new String("a");
时,常量池有一个 “a”,堆里有两个 String 对象,都指向常量池的 “a”
== 和 equals 的区别总结:
场景 | == | equals |
---|---|---|
基本数据类型(如 int) | 比数值是否相等 | 不能用(基本类型没有 equals 方法) |
引用数据类型(如 String) | 比对象地址是否相同 | 比对象内容是否相同(String 重写了 equals 方法) |
例子:
public class StringMemoryDemo {
public static void main(String[] args) {
String s1 = "abc"; // 常量池创建“abc”
String s2 = "abc"; // s2直接指向常量池的“abc”,地址相同
System.out.println(s1 == s2); // true(地址相同)
String s3 = new String("abc"); // 堆里新建对象,指向常量池的“abc”
String s4 = new String("abc"); // 堆里又新建对象,指向同一个“abc”
System.out.println(s3 == s4); // false(堆里地址不同)
System.out.println(s3.equals(s4)); // true(内容都是“abc”)
}
}
为什么 StringBuilder 拼接效率高
String 拼接时会生成新对象,比如s = s + "a"
,每次拼接都要创建新的 String 对象,效率低
StringBuilder 直接在内部数组里操作,不会频繁创建新对象,拼接效率高很多,尤其适合大量拼接的场景(如循环里拼接)