Java常见问题(二)
- 电脑硬件
- 2025-08-22 11:36:02

11. Java中的 throw 和 throws 有什么区别?
在Java中,throw 和 throws 都与异常处理相关,但它们的用途和行为有显著区别。
11.1 throw 关键字作用:
用于在代码中显式抛出一个异常。
通常用于在满足某些条件时主动抛出异常。
语法:
throw 异常对象;示例:
public class Main { public static void main(String[] args) { int age = -5; if (age < 0) { throw new IllegalArgumentException("年龄不能为负数"); // 抛出异常 } } }特点:
throw 用于方法内部。
抛出的异常必须是 Throwable 或其子类的实例。
抛出异常后,程序会立即停止当前方法的执行,并将异常传递给调用者。
11.2 throws 关键字作用:
用于方法签名中,声明该方法可能抛出的异常类型。
调用该方法时,必须处理这些异常(使用 try-catch 或继续向上抛出)。
语法:
返回类型 方法名(参数列表) throws 异常类型1, 异常类型2, ... { // 方法体 }示例:
public class Main { public static void main(String[] args) { try { readFile("file.txt"); } catch (IOException e) { System.out.println("捕获异常: " + e.getMessage()); } } static void readFile(String fileName) throws IOException { if (!fileName.equals("file.txt")) { throw new IOException("文件未找到"); // 抛出异常 } } }特点:
throws 用于方法签名中。
可以声明多个异常类型,用逗号分隔。
调用者必须处理这些异常,否则程序会编译失败。
11.3 throw 和 throws 的区别 特性throwthrows用途显式抛出一个异常声明方法可能抛出的异常类型位置方法内部方法签名中异常对象必须是一个具体的异常对象只需要指定异常类型调用者处理不需要在方法签名中声明调用者必须处理或继续抛出示例throw new Exception("错误");void method() throws Exception; 11.4 使用场景 (1)throw 的使用场景当方法内部检测到某些条件不满足时,主动抛出异常。
例如,参数校验、业务逻辑检查等。
(2)throws 的使用场景当方法内部可能抛出受检异常(checked exception),但不想在方法内部处理时,使用 throws 将异常传递给调用者。
例如,文件操作、网络操作等可能抛出 IOException 的场景。
11.5 注意事项受检异常 vs 非受检异常:
受检异常(checked exception):必须使用 throws 声明或在方法内部处理(如 IOException)。
非受检异常(unchecked exception):不需要使用 throws 声明(如 NullPointerException、IllegalArgumentException)。
方法重写时的 throws:
子类重写父类方法时,throws 声明的异常类型不能比父类方法更宽泛。
例如,父类方法声明 throws IOException,子类方法可以声明 throws FileNotFoundException(FileNotFoundException 是 IOException 的子类),但不能声明 throws Exception。
throw 和 throws 的结合使用:
可以在方法内部使用 throw 抛出异常,同时在方法签名中使用 throws 声明异常类型。
总结throw:用于在代码中显式抛出一个异常。
throws:用于方法签名中,声明该方法可能抛出的异常类型。
12. Java中的 interface 和 abstract class 有什么区别?在Java中,interface 和 abstract class 都是用于实现抽象和多态的重要机制,但它们在设计和使用上有显著的区别。
12.1 定义接口(Interface):
是一种完全抽象的类,只能包含抽象方法(Java 8 之前)。
从 Java 8 开始,接口可以包含默认方法(default 方法)和静态方法。
从 Java 9 开始,接口可以包含私有方法。
抽象类(Abstract Class):
是一种部分抽象的类,可以包含抽象方法和具体方法。
可以定义成员变量、构造器、普通方法和抽象方法。
12.2 主要区别 特性接口(Interface)抽象类(Abstract Class)方法实现Java 8 之前只能包含抽象方法;Java 8 开始可以包含默认方法和静态方法可以包含抽象方法和具体方法成员变量只能包含常量(默认是 public static final)可以包含普通成员变量和常量构造器不能定义构造器可以定义构造器多继承支持多继承(一个类可以实现多个接口)不支持多继承(一个类只能继承一个抽象类)默认访问修饰符方法默认是 public abstract方法可以是 public、protected 或默认访问修饰符设计目的定义行为规范(“能做什么”)定义类的部分实现(“是什么”和“能做什么”) 12.3 使用场景 (1)接口的使用场景定义一组行为规范,强调“能做什么”。
需要多继承时(一个类可以实现多个接口)。
适用于定义通用的功能,例如:
Runnable 接口定义线程任务。
Comparable 接口定义对象的比较规则。
(2)抽象类的使用场景定义部分实现,强调“是什么”和“能做什么”。
需要共享代码或状态时(抽象类可以包含成员变量和具体方法)。
适用于定义具有共同特征的类,例如:
动物类(Animal)可以定义抽象方法 sound(),子类(如 Dog、Cat)实现具体的叫声。
12.4 示例代码接口示例
interface Flyable { void fly(); // 抽象方法 default void land() { // 默认方法 System.out.println("正在降落"); } static void altitude() { // 静态方法 System.out.println("飞行高度"); } } class Bird implements Flyable { public void fly() { System.out.println("鸟在飞翔"); } } public class Main { public static void main(String[] args) { Bird bird = new Bird(); bird.fly(); // 输出: 鸟在飞翔 bird.land(); // 输出: 正在降落 Flyable.altitude(); // 输出: 飞行高度 } }抽象类示例
abstract class Animal { String name; Animal(String name) { this.name = name; } abstract void sound(); // 抽象方法 void sleep() { // 具体方法 System.out.println(name + " 正在睡觉"); } } class Dog extends Animal { Dog(String name) { super(name); } void sound() { System.out.println(name + " 汪汪叫"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog("小黑"); dog.sound(); // 输出: 小黑 汪汪叫 dog.sleep(); // 输出: 小黑 正在睡觉 } } 12.6 如何选择接口还是抽象类?使用接口:
需要定义一组行为规范。
需要多继承。
不关心具体实现细节。
使用抽象类:
需要共享代码或状态。
需要定义部分实现。
需要构造器或非静态成员变量。
13. Java中的 volatile 关键字有什么作用?在 Java 中,volatile 关键字用于修饰变量,主要作用是确保变量的可见性和禁止指令重排序。
13.1 可见性作用:当一个线程修改了 volatile 变量的值,其他线程能立即看到最新的值。
机制:volatile 变量不会被线程缓存,所有读写操作都直接在主内存中进行,保证了多线程环境下的可见性。
13.2 禁止指令重排序作用:防止 JVM 和处理器对指令进行重排序,确保代码执行顺序与编写顺序一致。
机制:volatile 变量的读写操作前后会插入内存屏障,防止重排序。
使用场景
状态标志:用于标记线程是否继续运行。
volatile boolean running = true; public void run() { while (running) { // 执行任务 } } public void stop() { running = false; }双重检查锁定(Double-Checked Locking):用于单例模式中,确保实例的唯一性。
class Singleton { private volatile static Singleton instance; public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }注意事项
不保证原子性:volatile 不能保证复合操作的原子性,如 i++。
性能影响:频繁读写 volatile 变量可能影响性能,因为每次操作都直接访问主内存。
总结volatile 关键字主要用于确保变量的可见性和防止指令重排序,适用于状态标志和双重检查锁定等场景,但不适用于需要原子性操作的场合。
14. Java中的 synchronized 关键字有什么作用?在 Java 中,synchronized 关键字用于实现线程同步,确保多个线程在访问共享资源时的线程安全。
14.1 互斥性(Mutual Exclusion)作用:synchronized 修饰的代码块或方法在同一时间只能被一个线程执行。
机制:通过获取对象的锁(monitor lock)来实现互斥。当一个线程进入 synchronized 代码块时,其他线程必须等待锁释放后才能进入。
14.2 可见性(Visibility)作用:确保线程对共享变量的修改对其他线程可见。
机制:在 synchronized 代码块或方法执行完成后,会将线程本地内存中的变量值刷新到主内存中;在进入 synchronized 代码块或方法时,会从主内存中读取最新的变量值。
使用方式synchronized 可以修饰以下两种形式:
1. 修饰实例方法
锁对象是当前实例(this)。
示例:
public synchronized void method() { // 线程安全的代码 }2. 修饰静态方法
锁对象是当前类的 Class 对象。
示例:
public static synchronized void staticMethod() { // 线程安全的代码 }3. 修饰代码块
需要显式指定锁对象。
示例:
public void method() { synchronized (this) { // 锁对象是当前实例 // 线程安全的代码 } } 使用场景保护共享资源:
当多个线程需要访问或修改共享资源时,使用 synchronized 可以避免数据不一致问题。
示例:
public class Counter { private int count = 0; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } }实现线程安全的单例模式:
使用 synchronized 确保单例对象的唯一性。
示例:
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }线程间通信:
结合 wait() 和 notify() 方法,实现线程间的协作。
示例:
public class SharedResource { private boolean isReady = false; public synchronized void waitUntilReady() throws InterruptedException { while (!isReady) { wait(); // 释放锁并等待 } } public synchronized void setReady() { isReady = true; notifyAll(); // 唤醒等待的线程 } } 注意事项性能开销:
synchronized 会引入锁竞争,可能导致线程阻塞,影响性能。
在高并发场景下,可以考虑使用更高效的并发工具(如 ReentrantLock 或 java.util.concurrent 包中的类)。
死锁风险:
如果多个线程互相持有对方需要的锁,可能导致死锁。
示例:
// 线程1 synchronized (lockA) { synchronized (lockB) { // 操作 } } // 线程2 synchronized (lockB) { synchronized (lockA) { // 操作 } }锁的范围:
尽量缩小同步代码块的范围,避免不必要的性能损耗。
总结synchronized 关键字是 Java 中最基本的线程同步机制,用于实现互斥性和可见性。它适用于保护共享资源、实现线程安全的单例模式以及线程间通信等场景。但在高并发场景下,需要注意性能开销和死锁风险,必要时可以使用更高级的并发工具。
15. Java中的 transient 关键字有什么作用?在 Java 中,transient 关键字用于修饰类的成员变量,其主要作用是阻止该变量被序列化。具体来说,当一个对象被序列化时,transient 修饰的变量不会被包含在序列化的数据中。
15.1 作用阻止序列化:transient 修饰的变量在对象序列化时会被忽略,不会被保存到文件或通过网络传输。
默认值:在反序列化时,transient 变量的值会被设置为默认值(如 int 类型为 0,对象类型为 null)。
15.2 使用场景敏感信息:
如果某些变量包含敏感信息(如密码、密钥等),可以使用 transient 修饰,避免序列化时泄露。
示例:
public class User implements Serializable { private String username; private transient String password; // 不会被序列化 // 构造方法、getter 和 setter }临时数据:
如果某些变量是临时数据或可以通过其他数据计算得出,可以使用 transient 修饰,避免不必要的序列化。
示例:
public class Data implements Serializable { private int value; private transient int cachedResult; // 临时缓存,不需要序列化 public int computeResult() { if (cachedResult == 0) { cachedResult = value * 2; // 假设这是一个计算过程 } return cachedResult; } }不可序列化的对象:
如果某个成员变量是不可序列化的对象(如 Thread 或 InputStream),可以使用 transient 修饰,避免序列化时抛出 NotSerializableException。
示例:
public class AppState implements Serializable { private String appName; private transient Thread workerThread; // 不可序列化的对象 } 15.3 注意事项反序列化时的初始化:
反序列化时,transient 变量的值会被设置为默认值。如果需要恢复这些变量的值,可以自定义 readObject 方法。
示例:
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); // 默认反序列化 this.password = "defaultPassword"; // 手动初始化 transient 变量 }与静态变量的区别:
transient 修饰的是实例变量,而静态变量(static)本身就不会被序列化,因此不需要使用 transient 修饰。
总结transient 关键字用于阻止变量被序列化,适用于保护敏感信息、避免序列化临时数据或不可序列化的对象。反序列化时,transient 变量的值会被设置为默认值,如果需要恢复其值,可以自定义 readObject 方法。
16. Java中的 Comparable 和 Comparator 有什么区别?在 Java 中,Comparable 和 Comparator 都是用于对象排序的接口,但它们的用途和实现方式有所不同。
16.1 Comparable定义:Comparable 是一个接口,定义在 java.lang 包中。
作用:用于实现对象的自然排序(即默认排序规则)。
方法:需要实现 compareTo(T o) 方法。
使用场景:当一个类有明确的自然排序规则时,可以实现 Comparable 接口。
示例:
public class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Person other) { return this.age - other.age; // 按年龄排序 } @Override public String toString() { return name + " (" + age + ")"; } public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("Alice", 30)); people.add(new Person("Bob", 25)); people.add(new Person("Charlie", 35)); Collections.sort(people); // 使用自然排序 System.out.println(people); // 输出:[Bob (25), Alice (30), Charlie (35)] } } 16.2 Comparator定义:Comparator 是一个接口,定义在 java.util 包中。
作用:用于实现对象的定制排序(即灵活的排序规则)。
方法:需要实现 compare(T o1, T o2) 方法。
使用场景:
当一个类没有实现 Comparable 接口时,可以通过 Comparator 进行排序。
当需要多种排序规则时,可以使用 Comparator。
示例:
import java.util.*; public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return name + " (" + age + ")"; } public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("Alice", 30)); people.add(new Person("Bob", 25)); people.add(new Person("Charlie", 35)); // 使用 Comparator 按姓名排序 Comparator<Person> nameComparator = new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name pareTo(p2.name); } }; Collections.sort(people, nameComparator); System.out.println(people); // 输出:[Alice (30), Bob (25), Charlie (35)] } } 16.3 区别对比 特性ComparableComparator包名java.langjava.util方法compareTo(To)compare(To1, To2)排序规则自然排序(默认排序规则)定制排序(灵活排序规则)实现位置在类内部实现在类外部实现使用场景单一排序规则多种排序规则修改排序规则需要修改类的代码不需要修改类的代码示例Collections.sort(list)Collections.sort(list, comparator) 16.4 使用建议使用 Comparable:
当类有明确的自然排序规则时。
例如,String 和 Integer 类都实现了 Comparable,因为它们有明确的排序规则。
使用 Comparator:
当需要多种排序规则时。
当无法修改类的源代码时(例如,使用第三方库的类)。
当需要临时定义排序规则时。
总结Comparable 用于定义对象的自然排序规则,适合单一排序场景。
Comparator 用于定义灵活的排序规则,适合多种排序场景。
17. Java中的 instanceof 关键字有什么作用?在 Java 中,instanceof 是一个二元操作符,用于检查一个对象是否是指定类型(类、接口或子类)的实例。
17.1 作用类型检查:判断一个对象是否属于某个类或其子类、接口的实现类。
避免类型转换异常:在类型转换之前使用 instanceof 进行检查,可以避免 ClassCastException。
17.2 语法 object instanceof Typeobject:需要检查的对象。
Type:目标类型(类、接口或子类)。
返回值:true 或 false。
17.3 使用场景1. 类型检查
在需要判断对象的实际类型时使用。
示例:
class Animal {} class Dog extends Animal {} class Cat extends Animal {} public class Main { public static void main(String[] args) { Animal myDog = new Dog(); Animal myCat = new Cat(); System.out.println(myDog instanceof Dog); // true System.out.println(myDog instanceof Animal); // true System.out.println(myCat instanceof Dog); // false } }2. 避免类型转换异常
在类型转换之前使用 instanceof 进行检查,确保转换的安全性。
示例:
Animal animal = new Dog(); if (animal instanceof Dog) { Dog dog = (Dog) animal; // 安全转换 System.out.println("This is a Dog."); } else { System.out.println("This is not a Dog."); }3. 多态场景下的类型判断
在处理多态对象时,instanceof 可以帮助确定对象的实际类型。
示例:
public void checkAnimal(Animal animal) { if (animal instanceof Dog) { System.out.println("This is a Dog."); } else if (animal instanceof Cat) { System.out.println("This is a Cat."); } else { System.out.println("This is an unknown Animal."); } }4. 接口实现检查
检查对象是否实现了某个接口。
示例:
interface Swimmable {} class Fish implements Swimmable {} class Bird {} public class Main { public static void main(String[] args) { Swimmable fish = new Fish(); Bird bird = new Bird(); System.out.println(fish instanceof Swimmable); // true System.out.println(bird instanceof Swimmable); // false } } 17.4 注意事项null 检查:
如果对象为 null,instanceof 会返回 false。
示例:
Animal animal = null; System.out.println(animal instanceof Animal); // false泛型类型擦除:
由于 Java 泛型的类型擦除机制,instanceof 不能直接用于泛型类型。
示例:
List<String> list = new ArrayList<>(); // 以下代码无法通过编译 // System.out.println(list instanceof List<String>);性能影响:
instanceof 的性能通常较好,但在高频调用时可能会影响性能。
总结instanceof 关键字用于检查对象是否属于某个类型,常用于类型检查、避免类型转换异常以及多态场景下的类型判断。它是 Java 中实现类型安全的重要工具,但在使用时需要注意 null 值和泛型类型擦除的限制。
18. Java中的 break 和 continue 有什么区别?在 Java 中,break 和 continue 都是用于控制循环流程的关键字,但它们的作用和行为有所不同。
18.1 break作用:立即终止当前循环(for、while、do-while 或 switch 语句),并跳出循环体。
使用场景:
当满足某个条件时,提前结束循环。
在 switch 语句中,用于跳出 case 分支。
示例:
for (int i = 1; i <= 10; i++) { if (i == 5) { break; // 当 i 等于 5 时,终止循环 } System.out.println(i); } // 输出:1 2 3 4 18.2 continue作用:跳过当前循环的剩余代码,直接进入下一次循环迭代。
使用场景:
当满足某个条件时,跳过当前迭代,继续执行下一次循环。
示例:
for (int i = 1; i <= 5; i++) { if (i == 3) { continue; // 当 i 等于 3 时,跳过本次循环 } System.out.println(i); } // 输出:1 2 4 5 18.3 区别对比 特性breakcontinue作用终止整个循环跳过当前迭代,继续下一次循环使用场景提前结束循环跳过某些特定条件的迭代循环行为循环完全结束循环继续执行,但跳过当前迭代适用语句for、while、do-while、switchfor、while、do-while 18.4 嵌套循环中的使用break:默认只跳出当前所在的循环。如果需要跳出外层循环,可以使用带标签的 break。
continue:默认只跳过当前循环的当前迭代。如果需要跳过外层循环的当前迭代,可以使用带标签的 continue。
带标签的 break 示例:
outerLoop: for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (i == 2 && j == 2) { break outerLoop; // 跳出外层循环 } System.out.println("i=" + i + ", j=" + j); } } // 输出: // i=1, j=1 // i=1, j=2 // i=1, j=3 // i=2, j=1带标签的 continue 示例:
outerLoop: for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (i == 2 && j == 2) { continue outerLoop; // 跳过外层循环的当前迭代 } System.out.println("i=" + i + ", j=" + j); } } // 输出: // i=1, j=1 // i=1, j=2 // i=1, j=3 // i=2, j=1 // i=3, j=1 // i=3, j=2 // i=3, j=3 总结break:用于完全终止循环,适用于提前结束循环或跳出 switch 语句。
continue:用于跳过当前迭代,继续执行下一次循环,适用于跳过某些特定条件的迭代。
在嵌套循环中,可以使用带标签的 break 和 continue 来控制外层循环的行为。
19. Java中的 Math 类有哪些常用方法?Java 中的 Math 类提供了许多用于数学运算的静态方法。
19.1 基本运算abs(int a), abs(long a), abs(float a), abs(double a) 返回参数的绝对值。
max(int a, int b), max(long a, long b), max(float a, float b), max(double a, double b) 返回两个参数中的较大值。
min(int a, int b), min(long a, long b), min(float a, float b), min(double a, double b) 返回两个参数中的较小值。
19.2 指数和对数pow(double a, double b) 返回 a 的 b 次方。
sqrt(double a) 返回 a 的平方根。
exp(double a) 返回自然对数底数 e 的 a 次方。
log(double a) 返回 a 的自然对数(以 e 为底)。
log10(double a) 返回 a 的以 10 为底的对数。
19.3 三角函数sin(double a) 返回角度的正弦值(角度以弧度表示)。
cos(double a) 返回角度的余弦值(角度以弧度表示)。
tan(double a) 返回角度的正切值(角度以弧度表示)。
asin(double a) 返回 a 的反正弦值(结果以弧度表示)。
acos(double a) 返回 a 的反余弦值(结果以弧度表示)。
atan(double a) 返回 a 的反正切值(结果以弧度表示)。
atan2(double y, double x) 返回从直角坐标 (x, y) 到极坐标 (r, theta) 的转换角度 theta。
19.4 舍入运算ceil(double a) 返回大于或等于 a 的最小整数(向上取整)。
floor(double a) 返回小于或等于 a 的最大整数(向下取整)。
round(float a), round(double a) 返回最接近 a 的整数(四舍五入)。
19.5 随机数random() 返回一个 [0.0, 1.0) 范围内的伪随机 double 值。
19.6 其他toRadians(double angdeg) 将角度转换为弧度。
toDegrees(double angrad) 将弧度转换为角度。
hypot(double x, double y) 返回 sqrt(x² + y²),即直角三角形的斜边长度。
copySign(double magnitude, double sign) 返回一个与 sign 同符号的 magnitude 值。
nextAfter(double start, double direction) 返回与 start 相邻的、朝向 direction 的浮点数。
nextUp(double d) 返回比 d 大的最小浮点数。
nextDown(double d) 返回比 d 小的最大浮点数。
20. Java中的 Arrays 类有哪些常用方法?java.util.Arrays 类是 Java 中用于操作数组的工具类,提供了许多静态方法来处理数组。
20.1 排序sort(array): 对数组进行升序排序。
int[] arr = {5, 3, 1, 4, 2}; Arrays.sort(arr); // arr 现在是 [1, 2, 3, 4, 5]sort(array, fromIndex, toIndex): 对数组的指定范围进行排序。
int[] arr = {5, 3, 1, 4, 2}; Arrays.sort(arr, 1, 4); // arr 现在是 [5, 1, 3, 4, 2] 20.2 二分查找binarySearch(array, key): 在已排序的数组中使用二分查找法查找指定元素,返回索引。如果未找到,返回负数。
int[] arr = {1, 2, 3, 4, 5}; int index = Arrays.binarySearch(arr, 3); // index 是 2binarySearch(array, fromIndex, toIndex, key): 在数组的指定范围内进行二分查找。
int[] arr = {1, 2, 3, 4, 5}; int index = Arrays.binarySearch(arr, 1, 4, 3); // index 是 2 20.3 比较equals(array1, array2): 比较两个数组是否相等(元素顺序和值相同)。
int[] arr1 = {1, 2, 3}; int[] arr2 = {1, 2, 3}; boolean isEqual = Arrays.equals(arr1, arr2); // isEqual 是 true 20.4 填充fill(array, value): 将数组的所有元素填充为指定值。
int[] arr = new int[5]; Arrays.fill(arr, 10); // arr 现在是 [10, 10, 10, 10, 10]fill(array, fromIndex, toIndex, value): 将数组的指定范围填充为指定值。
int[] arr = new int[5]; Arrays.fill(arr, 1, 4, 10); // arr 现在是 [0, 10, 10, 10, 0] 20.5 复制copyOf(original, newLength): 复制数组,指定新数组的长度。
int[] arr = {1, 2, 3}; int[] newArr = Arrays.copyOf(arr, 5); // newArr 现在是 [1, 2, 3, 0, 0]copyOfRange(original, from, to): 复制数组的指定范围。
int[] arr = {1, 2, 3, 4, 5}; int[] newArr = Arrays.copyOfRange(arr, 1, 4); // newArr 现在是 [2, 3, 4] 20.6 转换为字符串toString(array): 将数组转换为字符串表示形式。
int[] arr = {1, 2, 3}; String str = Arrays.toString(arr); // str 是 "[1, 2, 3]" 20.7 哈希码hashCode(array): 返回数组的哈希码。
int[] arr = {1, 2, 3}; int hashCode = Arrays.hashCode(arr); 20.8 流操作stream(array): 将数组转换为流。
int[] arr = {1, 2, 3}; IntStream stream = Arrays.stream(arr); 20.9 并行排序parallelSort(array): 对数组进行并行排序。
int[] arr = {5, 3, 1, 4, 2}; Arrays.parallelSort(arr); // arr 现在是 [1, 2, 3, 4, 5]parallelSort(array, fromIndex, toIndex): 对数组的指定范围进行并行排序。
int[] arr = {5, 3, 1, 4, 2}; Arrays.parallelSort(arr, 1, 4); // arr 现在是 [5, 1, 3, 4, 2] 20.10 比较器排序sort(array, comparator): 使用自定义比较器对数组进行排序。
String[] arr = {"apple", "banana", "cherry"}; Arrays.sort(arr, (a, b) -> b pareTo(a)); // arr 现在是 ["cherry", "banana", "apple"] 20.11 并行前缀计算parallelPrefix(array, op): 对数组进行并行前缀计算。
int[] arr = {1, 2, 3, 4}; Arrays.parallelPrefix(arr, (a, b) -> a + b); // arr 现在是 [1, 3, 6, 10] 20.12 集合转换asList(array): 将数组转换为固定大小的列表。
String[] arr = {"a", "b", "c"}; List<String> list = Arrays.asList(arr); // list 是 ["a", "b", "c"] 21. Java中的 Collections 类有哪些常用方法?java.util.Collections 类是 Java 中用于操作集合(如 List、Set、Map 等)的工具类,提供了许多静态方法来处理集合。
21.1 排序sort(list): 对列表进行升序排序。
List<Integer> list = Arrays.asList(5, 3, 1, 4, 2); Collections.sort(list); // list 现在是 [1, 2, 3, 4, 5]sort(list, comparator): 使用自定义比较器对列表进行排序。
List<String> list = Arrays.asList("apple", "banana", "cherry"); Collections.sort(list, (a, b) -> b pareTo(a)); // list 现在是 ["cherry", "banana", "apple"] 21.2 二分查找binarySearch(list, key): 在已排序的列表中使用二分查找法查找指定元素,返回索引。如果未找到,返回负数。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int index = Collections.binarySearch(list, 3); // index 是 2binarySearch(list, key, comparator): 使用自定义比较器在已排序的列表中进行二分查找。
List<String> list = Arrays.asList("cherry", "banana", "apple"); int index = Collections.binarySearch(list, "banana", (a, b) -> b pareTo(a)); // index 是 1 21.3 反转reverse(list): 反转列表中的元素顺序。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Collections.reverse(list); // list 现在是 [5, 4, 3, 2, 1] 21.4 随机打乱shuffle(list): 随机打乱列表中的元素顺序。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Collections.shuffle(list); // list 现在是随机顺序,例如 [3, 1, 5, 2, 4]shuffle(list, random): 使用指定的随机源打乱列表中的元素顺序。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Collections.shuffle(list, new Random()); // list 现在是随机顺序,例如 [4, 2, 1, 5, 3] 21.5 填充fill(list, value): 将列表的所有元素填充为指定值。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Collections.fill(list, 10); // list 现在是 [10, 10, 10, 10, 10] 21.6 复制copy(dest, src): 将源列表中的元素复制到目标列表中。
List<Integer> src = Arrays.asList(1, 2, 3); List<Integer> dest = Arrays.asList(4, 5, 6, 7, 8); Collections.copy(dest, src); // dest 现在是 [1, 2, 3, 7, 8] 21.7 最小值和最大值min(collection): 返回集合中的最小元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int min = Collections.min(list); // min 是 1max(collection): 返回集合中的最大元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int max = Collections.max(list); // max 是 5min(collection, comparator): 使用自定义比较器返回集合中的最小元素。
List<String> list = Arrays.asList("apple", "banana", "cherry"); String min = Collections.min(list, (a, b) -> b pareTo(a)); // min 是 "cherry"max(collection, comparator): 使用自定义比较器返回集合中的最大元素。
List<String> list = Arrays.asList("apple", "banana", "cherry"); String max = Collections.max(list, (a, b) -> b pareTo(a)); // max 是 "apple" 21.8 替换replaceAll(list, oldVal, newVal): 将列表中的所有旧值替换为新值。
List<String> list = Arrays.asList("apple", "banana", "apple"); Collections.replaceAll(list, "apple", "orange"); // list 现在是 ["orange", "banana", "orange"] 21.9 频率frequency(collection, obj): 返回集合中指定元素的出现次数。
List<String> list = Arrays.asList("apple", "banana", "apple"); int freq = Collections.frequency(list, "apple"); // freq 是 2 21.10 不可变集合unmodifiableCollection(collection): 返回一个不可修改的集合视图。
List<String> list = Arrays.asList("apple", "banana", "cherry"); Collection<String> unmodifiableList = Collections.unmodifiableCollection(list); // unmodifiableList 是不可修改的unmodifiableList(list): 返回一个不可修改的列表视图。
List<String> list = Arrays.asList("apple", "banana", "cherry"); List<String> unmodifiableList = Collections.unmodifiableList(list); // unmodifiableList 是不可修改的unmodifiableSet(set): 返回一个不可修改的集合视图。
Set<String> set = new HashSet<>(Arrays.asList("apple", "banana", "cherry")); Set<String> unmodifiableSet = Collections.unmodifiableSet(set); // unmodifiableSet 是不可修改的unmodifiableMap(map): 返回一个不可修改的映射视图。
Map<String, Integer> map = new HashMap<>(); map.put("apple", 1); map.put("banana", 2); Map<String, Integer> unmodifiableMap = Collections.unmodifiableMap(map); // unmodifiableMap 是不可修改的 21.11 同步集合synchronizedCollection(collection): 返回一个线程安全的集合。
Collection<String> collection = new ArrayList<>(); Collection<String> syncCollection = Collections.synchronizedCollection(collection); // syncCollection 是线程安全的synchronizedList(list): 返回一个线程安全的列表。
List<String> list = new ArrayList<>(); List<String> syncList = Collections.synchronizedList(list); // syncList 是线程安全的synchronizedSet(set): 返回一个线程安全的集合。
Set<String> set = new HashSet<>(); Set<String> syncSet = Collections.synchronizedSet(set); // syncSet 是线程安全的synchronizedMap(map): 返回一个线程安全的映射。
Map<String, Integer> map = new HashMap<>(); Map<String, Integer> syncMap = Collections.synchronizedMap(map); // syncMap 是线程安全的 21.12 单元素集合singletonList(obj): 返回一个只包含指定对象的不可变列表。
List<String> list = Collections.singletonList("apple"); // list 是 ["apple"]singletonSet(obj): 返回一个只包含指定对象的不可变集合。
Set<String> set = Collections.singletonSet("apple"); // set 是 ["apple"]singletonMap(key, value): 返回一个只包含指定键值对的不可变映射。
Map<String, Integer> map = Collections.singletonMap("apple", 1); // map 是 {"apple": 1} 21.13 空集合emptyList(): 返回一个空的不可变列表。
List<String> list = Collections.emptyList(); // list 是 []emptySet(): 返回一个空的不可变集合。
Set<String> set = Collections.emptySet(); // set 是 []emptyMap(): 返回一个空的不可变映射。
Map<String, Integer> map = Collections.emptyMap(); // map 是 {} 21.14 检查集合是否为空isEmpty(collection): 检查集合是否为空。
List<String> list = new ArrayList<>(); boolean isEmpty = Collections.isEmpty(list); // isEmpty 是 true 21.15 反转比较器reverseOrder(): 返回一个反转自然顺序的比较器。
List<String> list = Arrays.asList("apple", "banana", "cherry"); Collections.sort(list, Collections.reverseOrder()); // list 现在是 ["cherry", "banana", "apple"]reverseOrder(comparator): 返回一个反转指定比较器顺序的比较器。
List<String> list = Arrays.asList("apple", "banana", "cherry"); Collections.sort(list, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER)); // list 现在是 ["cherry", "banana", "apple"]Java常见问题(二)由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Java常见问题(二)”