1. API
1.1 API 概述
什么是 API?
API (Application Programming Interface) 是应用程序编程接口,它是一组工具、类、方法和规则,使不同的应用程序可以通过接口进行数据交互和操作。API 的作用主要是:
- 封装复杂性:提供简单的接口供开发者调用,不需要关心底层实现的细节。
- 提高复用性:通过提供公共的功能模块,减少重复实现相同功能的代码。
- 统一标准:API 通常是标准化的,保证不同的开发者、系统或平台可以协同工作。
Java 中的 API
在 Java 中,API 指 JDK 提供的类、接口、方法等,它们封装了大量基础功能,如数据结构、输入输出、网络编程、多线程等。Java API 是开发者进行 Java 编程的基础工具。
例如,java.util.Random
类用于生成随机数,它提供了一些生成随机整数、浮点数、布尔值的方法。开发者通过 Java API,可以快速实现随机数的功能,而无需编写底层的生成逻辑。
1.2 如何使用 API 帮助文档
使用 API 帮助文档的步骤:
-
打开 Java API 文档:可以通过访问 Oracle 官方文档 或者通过 IDE 中的帮助功能打开。
-
索引检索:通过搜索框输入你要查询的类名或方法名,例如输入
Random
。 -
查找类所在包:文档会显示类的所属包,例如
java.util.Random
在java.util
包下。 -
查看类的描述:文档会详细描述类的用途、适用场景、以及该类的设计目的。
-
查看构造方法:了解如何创建类的实例。
-
查看成员方法:通过帮助文档中的方法列表,可以查看类中提供的所有方法,以及每个方法的详细用法和参数列表。
帮助文档不仅能帮助你理解某个类的用法,还能帮助你找到更合适的类来解决问题。
2. String 类
2.1 String 类概述
String
类用于表示字符串,是 Java 中非常基础和常用的类。Java 中所有的字符串字面量(例如 "abc"
)都是 String
类的实例,且 String
类位于 java.lang
包下,不需要手动导包。
String 的特点:
- 不可变性:一旦创建了字符串对象,字符串中的字符是无法更改的。修改操作会生成新的字符串对象,旧的对象不会被改变。这种不可变性使得
String
在多线程环境下是安全的。 - 字符串池:为了节省内存,JVM 会将常量字符串存储在字符串池中。如果两个字符串内容相同且是通过字面量赋值创建的,JVM 不会为每个字符串单独分配内存,而是重用相同的字符串对象。
扩展:
-
为什么 String 不可变?
- 不可变性带来安全性和效率。比如在网络传输、文件读写等场景中,多个对象可能会引用同一个字符串对象,如果字符串是可变的,则任何一个对象的修改都会影响到其他对象的行为。而不可变的设计使得多个引用是安全的。
-
字符串池的实现机制:
- 字符串池存储在堆内存中,JVM 在创建字符串字面量时首先会检查字符串池中是否已经存在相同内容的字符串对象,如果存在,直接返回该对象的引用;如果不存在,则会创建新的字符串对象并将其放入池中。
2.2 String 类的构造方法
String()
:创建一个空的字符串对象。String(char[] value)
:通过字符数组创建字符串对象。String(byte[] value)
:通过字节数组创建字符串对象。String(String original)
:拷贝现有的字符串对象,创建新的字符串。
2.3 创建字符串对象的两种方式的区别
-
通过构造方法创建:
- 使用
new String()
创建字符串时,无论内容是否相同,都会在堆中创建新的对象,每次new
都会分配新的内存空间。因此,new String("abc")
创建了两个对象,一个是字符串池中的"abc"
,另一个是堆中的String
对象。
- 使用
-
通过字面量赋值创建:
- 如果通过字面量创建字符串,JVM 会首先在字符串池中查找是否存在相同内容的字符串。如果存在,直接返回字符串池中的引用;如果不存在,才会在池中创建新的字符串。因此,字符串字面量赋值不会创建新的对象,能够节省内存。
2.4 字符串的比较
== 运算符:
- 基本数据类型:
==
比较的是数值本身。 - 引用数据类型:
==
比较的是两个对象的内存地址,只有当两个引用指向相同的内存地址时,==
才会返回true
。
equals() 方法:
equals()
用于比较两个字符串对象的内容是否相同,它是String
类中重写的Object
类的equals()
方法。equals()
默认情况下区分大小写,如果需要忽略大小写的比较,可以使用equalsIgnoreCase()
方法。
String str1 = new String("abc");
String str2 = "abc";
System.out.println(str1 == str2); // false, 因为内存地址不同
System.out.println(str1.equals(str2)); // true, 因为内容相同
扩展:
-
为什么需要 equals() 方法?
- 因为
==
比较的是内存地址,无法判断两个字符串内容是否相同。而equals()
是按值比较,通过遍历两个字符串的每个字符来判断它们的内容是否一致。
- 因为
-
字符串池的作用:
- 字符串池允许相同的字符串只存在一个实例,从而减少了内存开销。
equals()
方法适合用来比较字符串内容,因为它可以正确处理字符串池中的共享实例问题。
- 字符串池允许相同的字符串只存在一个实例,从而减少了内存开销。
3. StringBuilder 类
3.1 概述
StringBuilder
是一个可变的字符序列类,用于在字符串内容需要频繁修改时提升性能。它提供了更高效的字符串拼接和修改操作,相比于 String
类,StringBuilder
可以避免产生大量的中间对象。
- 性能优势:
StringBuilder
通过直接操作同一个字符序列来进行字符串的拼接和修改,避免了String
类每次修改内容时重新创建对象的开销。 - 非线程安全:
StringBuilder
是非线程安全的,适合单线程环境下使用。如果需要在多线程环境中使用,应选择StringBuffer
类,它是线程安全的版本。
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // 拼接
sb.reverse(); // 反转
System.out.println(sb.toString()); // 输出 "dlroW olleH"
3.2 链式调用
StringBuilder
的 append()
、insert()
等方法返回当前对象本身,因此可以通过链式调用简化代码书写。
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" ").append("World");
System.out.println(sb.toString()); // 输出 "Hello World"
扩展:
- StringBuilder 和 String 的区别:
StringBuilder
适用于需要频繁修改字符串的场景,String
适用于内容不变的场景。- 由于
StringBuilder
是可变的,因此它可以在原有的字符序列上进行修改,性能更高。
- 线程安全:
- 如果需要在多线程中使用
StringBuilder
,请使用StringBuffer
,它通过同步机制保证线程安全。
- 如果需要在多线程中使用
4. StringJoiner 类(JDK 8 之后新增)
4.1 概述
StringJoiner
是 Java 8 引入的一个类,用于高效地将多个字符串拼接在一起,并且可以通过指定分隔符、前缀和后缀来格式化输出。相比于 StringBuilder
,StringJoiner
更适合用于将多个字符串组合为单个字符串的场景。
示例代码:
StringJoiner sj = new StringJoiner(", ", "[", "]");
sj.add("Hello").add("World").add("Java");
System.out.println(sj.toString()); // 输出 "[Hello, World, Java]"
-
参数解释:
,
:分隔符,字符串之间用逗号和空格分隔。[
:前缀,表示整个字符串的起始符号。]
:后缀,表示整个字符串的结束符号。
扩展:
-
性能对比:
StringJoiner
适用于需要按照某种规则拼接字符串的场景,相比于手动使用StringBuilder
添加分隔符、前缀和后缀,StringJoiner
提供了更便捷的方式。
5. 结语
Java 提供了丰富的字符串处理工具类,如 String
、StringBuilder
和 StringJoiner
。合理选择和使用这些类可以大幅提升程序的性能和可维护性。在实际开发中,建议根据场景选择最合适的类,如:
-
对于不需要修改的字符串使用
String
; -
需要频繁修改字符串时使用
StringBuilder
; -
需要以固定格式拼接多个字符串时使用
StringJoiner
。
ring、
StringBuilder和
StringJoiner`。合理选择和使用这些类可以大幅提升程序的性能和可维护性。在实际开发中,建议根据场景选择最合适的类,如: -
对于不需要修改的字符串使用
String
; -
需要频繁修改字符串时使用
StringBuilder
; -
需要以固定格式拼接多个字符串时使用
StringJoiner
。