1. 使用StringBuilder优化字符串拼接:
// 不优化的写法
String result = "";
for (int i = 0; i < 1000; i++) {
result += i;
}
// 优化的写法
StringBuilder resultBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
resultBuilder.append(i);
}
String result = resultBuilder.toString();
2. 避免在循环中重复计算数组长度:
// 不优化的写法
for (int i = 0; i < array.length; i++) {
// 访问数组元素
}
// 优化的写法
int length = array.length;
for (int i = 0; i < length; i++) {
// 访问数组元素
}
3. 使用局部变量替代重复调用方法:类似2
// 不优化的写法
for (int i = 0; i < list.size(); i++) {
// 多次调用list.get(i)
}
// 优化的写法
int size = list.size();
for (int i = 0; i < size; i++) {
// 多次使用size
// 使用list.get(i)
}
4. 选择合适的集合类:
// 使用ArrayList而不是LinkedList,发明LinkedList都不用LinkedList,可想而知
List<String> arrayList = new ArrayList<>();
// 使用HashSet而不是TreeSet,TreeSet排序消耗性能,但大多数情况下都没必要排序
Set<String> hashSet = new HashSet<>();
5. 合理使用缓存:
// 缓存计算结果
Map<Integer, Integer> cache = new HashMap<>();
int result = cache.computeIfAbsent(input, key -> computeExpensiveOperation(key));
6. 避免过度同步:
// 避免过度同步(锁粒度要尽量最小)
private static final Object lock = new Object();
synchronized (lock) {
// 一些同步操作
}
7. 使用适当的算法和数据结构:
// 使用Arrays.sort()进行排序
int[] array = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
Arrays.sort(array);
Arrays.sort()
使用了一种高效的排序算法(通常是基于快速排序的变体),在大多数情况下,它能够以较高的性能对数组进行排序。
8. 减少对象创建:
// 减少对象创建
StringBuilder resultBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
resultBuilder.append(i);
}
String result = resultBuilder.toString();
9. 使用快速失败机制:
// 使用Iterator并快速失败机制
List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
// 对element进行操作
}
如果在遍历集合的过程中,其他线程对集合进行了结构性的修改(比如添加或删除元素),快速失败机制会立即抛出ConcurrentModificationException
,以通知集合已经被修改,避免在不一致的状态下继续操作。
10. 使用多线程:
// 使用多线程
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> {
// 在线程中执行的代码
});
executor.shutdown();
11. 避免不必要的IO操作:
// 避免不必要的IO操作
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
// 读取文件内容
} catch (IOException e) {
e.printStackTrace();
}
12. 使用位运算代替乘除法:
// 使用位运算代替乘法
int result = 5 << 2; // 相当于 5 * 2^2 = 20
13. 避免不必要的装箱和拆箱:
// 不优化的写法
Integer sum = 0;
for (int i = 0; i < 1000; i++) {
sum += i; // 自动装箱和拆箱
}
// 优化的写法
int sum = 0;
for (int i = 0; i < 1000; i++) {
sum += i;
}
14. 使用静态工厂方法创建对象:
// 不优化的写法
Date now = new Date();
// 优化的写法
Date now = Date.from(Instant.now());
15. 合理使用try-with-resources:
// 不优化的写法
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("file.txt"));
// 读取文件内容
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 优化的写法
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
// 读取文件内容
} catch (IOException e) {
e.printStackTrace();
}
16. 使用Lambda表达式简化代码:
// 不优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
// 优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(System.out::println);
17. 使用并发集合提高多线程性能:
// 不优化的写法
List<String> list = new ArrayList<>();
// 在多线程环境下可能会有并发问题
// 优化的写法
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
// 或者使用并发集合类
List<String> concurrentList = new CopyOnWriteArrayList<>();
18. 使用Stream API进行集合操作:
// 不优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> uppercaseNames = new ArrayList<>();
for (String name : names) {
uppercaseNames.add(name.toUpperCase());
}
// 优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> uppercaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
19. 使用局部变量替代字段访问:
// 不优化的写法
class MyClass {
private int myField;
public int calculate() {
return myField * 2;
}
}
// 优化的写法
class MyClass {
private int myField;
public int calculate() {
int localVar = myField;
return localVar * 2;
}
}
使用局部变量替代直接访问字段的做法,是为了在方法内部使用字段的值时,提供更好的可读性和安全性。
20. 使用ConcurrentHashMap代替同步Map:
// 不优化的写法
Map<String, Integer> map = new HashMap<>();
// 在多线程环境下需要额外的同步机制
// 优化的写法
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
21. 避免在循环中创建对象:
// 不优化的写法
List<String> myList = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
myList.add(new String("Element" + i));
}
// 优化的写法
List<String> myList = new ArrayList<>();
String elementPrefix = "Element";
for (int i = 0; i < 1000; i++) {
myList.add(elementPrefix + i);
}
22. 使用接口代替继承:
// 不优化的写法
class MyList extends ArrayList<String> {
// ...
}
// 优化的写法
List<String> myList = new ArrayList<>();
使用接口代替继承的原则是基于面向接口编程的设计理念,有几个原因支持这种优化方式:
- 松耦合(Loose Coupling): 使用接口使得类之间的关系更加灵活,降低了各个类之间的耦合度。在不使用具体实现类的情况下,通过接口可以更容易地替换具体的实现,使系统更加灵活和可维护。
- 多态性(Polymorphism): 通过使用接口,可以实现多态性。即一个类可以以多种形式存在,不同类的对象可以使用相同的接口进行引用,提高代码的灵活性。
- 遵循"合成优于继承"原则: 继承通常引入了额外的复杂性和依赖关系,而使用接口更加简单。合成是指通过组合现有的类和接口来创建新的类,而不是通过继承已有的类。这有助于更好地组织和维护代码。
23. 使用正则表达式进行字符串操作:
// 不优化的写法
String result = "Hello, World!".replace("Hello", "Hi");
// 优化的写法
Pattern pattern = Pattern.compile("Hello");
Matcher matcher = pattern.matcher("Hello, World!");
String result = matcher.replaceFirst("Hi");
通过使用正则表达式的方式,可以更好地应对一些更为复杂的字符串操作需求。然而,对于简单的字符串替换操作,直接使用 replace
方法可能更加简洁和易读。
24. 合理使用断言:
// 不优化的写法
if (condition) {
throw new IllegalStateException("Condition not met");
}
// 优化的写法
assert condition : "Condition not met";
25. 合理使用enum代替常量:
// 不优化的写法
public static final int STATUS_PENDING = 1;
public static final int STATUS_PROCESSING = 2;
public static final int STATUS_COMPLETED = 3;
// 优化的写法
public enum Status {
PENDING, PROCESSING, COMPLETED;
}
26. 使用连接池:
// 不优化的写法
Connection connection = DriverManager.getConnection(url, username, password);
// 每次都创建新的数据库连接
// 优化的写法
DataSource dataSource = // 初始化数据源(比如 HikariCP)
try (Connection connection = dataSource.getConnection()) {
// 使用连接
}
27. 使用并行流进行并行计算:
// 不优化的写法
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.stream()
.mapToInt(Integer::intValue)
.sum();
// 优化的写法
int sum = numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();
优势:
- 并行性: 使用并行流可以在多个线程上并行执行操作,加速对大型数据集的处理,特别是在现代多核处理器上。
- 简化并行计算: 并行流能够将并行计算的复杂性封装在底层框架中,使得无需手动管理线程。
- 适用于某些操作: 并行流在某些类型的操作(如大量数据的过滤、映射、聚合等)上表现得更好。
28. 使用异步编程提高并发性能:
// 不优化的写法
Future<Integer> future = executorService.submit(() -> {
// 执行耗时操作
return result;
});
// 优化的写法
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
// 执行耗时操作
return result;
}, executorService);
29. 使用单例模式减少对象创建:
// 不优化的写法
class NonSingleton {
// ...
}
NonSingleton instance = new NonSingleton();
// 优化的写法
class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
// 私有构造函数
}
public static Singleton getInstance() {
return INSTANCE;
}
}
Singleton instance = Singleton.getInstance();
30. 使用String.contains检查字符串中是否包含子串:
// 不优化的写法
String text = "Hello, World!";
if (text.indexOf("World") != -1) {
// 处理逻辑
}
// 优化的写法
String text = "Hello, World!";
if (text.contains("World")) {
// 处理逻辑
}
31. 使用接口和抽象类进行代码设计:
// 不优化的写法
class Dog {
void bark() {
// 狗的吠叫逻辑
}
}
class Cat {
void meow() {
// 猫的喵叫逻辑
}
}
// 优化的写法
interface Animal {
void makeSound();
}
class Dog implements Animal {
@Override
public void makeSound() {
// 狗的吠叫逻辑
}
}
class Cat implements Animal {
@Override
public void makeSound() {
// 猫的喵叫逻辑
}
32. 使用lambda表达式简化匿名类:
// 不优化的写法
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Running");
}
};
// 优化的写法
Runnable runnable = () -> System.out.println("Running");
33. 避免在循环中进行数据库查询:
// 不优化的写法
List<String> ids = // 获取一堆ID
for (String id : ids) {
User user = userRepository.findById(id);
// 处理用户对象
}
// 优化的写法
List<String> ids = // 获取一堆ID
List<User> users = userRepository.findAllById(ids);
for (User user : users) {
// 处理用户对象
}
34. 使用适当的日志级别:
// 不优化的写法
if (logger.isDebugEnabled()) {
logger.debug("Some debug information: " + expensiveOperation());
}
// 优化的写法
logger.debug("Some debug information: {}", expensiveOperation());
35. 减小方法的长度:
将大的方法拆分为小的方法,有助于提高代码的可读性和维护性。
拿阿里巴巴的开发手册来说,并没有明确规定一个方法的具体行数上限,而是提倡按照 Single Responsibility Principle(单一职责原则)和合理拆分的原则来组织代码。然而,根据阿里巴巴的《Java 开发手册》中的一些建议,可以总结一些编码规范和最佳实践,其中也包括关于方法长度的一些建议:
- Single Responsibility Principle: 一个方法应该只做一件事情。如果一个方法的功能变得复杂,可以考虑将其拆分为多个小方法,每个小方法负责一个明确的子任务。
- 规范注释: 阿里巴巴建议在方法前使用规范注释,明确方法的功能、输入参数、输出结果等信息。如果一个方法的功能需要过多的注释来解释,可能需要考虑拆分。
- 控制复杂度: 阿里巴巴建议控制单个方法的复杂度,尽量避免过多的嵌套结构和冗长的代码。这也暗示了一个方法不应该过长。
36. 使用延迟初始化:
// 不优化的写法
class MyClass {
private ExpensiveObject expensiveObject = new ExpensiveObject();
public ExpensiveObject getExpensiveObject() {
return expensiveObject;
}
}
// 优化的写法
class MyClass {
private ExpensiveObject expensiveObject;
public ExpensiveObject getExpensiveObject() {
if (expensiveObject == null) {
expensiveObject = new ExpensiveObject();
}
return expensiveObject;
}
}
37. 使用异步IO:
// 不优化的写法
InputStream inputStream = new FileInputStream("file.txt");
// 读取文件操作,可能会阻塞线程
// 优化的写法
AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get("file.txt"));
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
// 异步读取完成后的处理逻辑
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
// 处理读取失败的逻辑
}
});
38. 使用位集(BitSet)进行位操作:
// 不优化的写法
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
// 优化的写法
BitSet bitSet = new BitSet();
bitSet.set(1);
bitSet.set(2);
39. 使用List.contains检查集合中是否存在元素:
// 不优化的写法
List<String> myList = Arrays.asList("Apple", "Banana", "Orange");
if (myList.indexOf("Banana") != -1) {
// 处理逻辑
}
// 优化的写法
List<String> myList = Arrays.asList("Apple", "Banana", "Orange");
if (myList.contains("Banana")) {
// 处理逻辑
}
40. 使用Files.exists检查文件是否存在:
// 不优化的写法
File file = new File("lfsun.txt");
if (file.exists()) {
// 处理逻辑
}
// 优化的写法
Path path = Paths.get("lfsun.txt");
if (Files.exists(path)) {
// 处理逻辑
}
41. 使用Math.min和Math.max获取两个数的最小和最大值:
// 不优化的写法
int a = 5;
int b = 10;
int minValue = (a < b) ? a : b;
int maxValue = (a > b) ? a : b;
// 优化的写法
int a = 5;
int b = 10;
int minValue = Math.min(a, b);
int maxValue = Math.max(a, b);
42. 使用File.separator构建跨平台的文件路径:
// 不优化的写法
String path = "dir\file.txt";
// 优化的写法
String path = "dir" + File.separator + "file.txt";
43. 使用String.trim去除字符串两端的空格:
// 不优化的写法
String text = " Hello, World! ";
String trimmedText = text.replaceAll("^\s+|\s+$", "");
// 优化的写法
String text = " Hello, World! ";
String trimmedText = text.trim();
44. 使用String.startsWith和String.endsWith检查字符串前缀和后缀:
// 不优化的写法
String text = "Hello, World!";
if (text.indexOf("Hello") == 0) {
// 处理逻辑
}
// 优化的写法
String text = "Hello, World!";
if (text.startsWith("Hello")) {
// 处理逻辑
}
45. 使用LocalDateTime和DateTimeFormatter进行日期时间格式化:
// 不优化的写法
Date currentDate = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formattedDate = sdf.format(currentDate);
// 优化的写法
LocalDateTime currentDateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = currentDateTime.format(formatter);
46. 使用String.substring截取子字符串:
// 不优化的写法
String text = "Hello, World";
String substring = text.substring(7, 12);
// 优化的写法
String text = "Hello, World";
String substring = text.substring(7);
47. 使用ThreadLocal减少线程间共享变量:
// 不优化的写法
class SharedResource {
private int value;
// ...
}
// 优化的写法
class SharedResource {
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
// ...
}
48. 使用可变参数改善方法的灵活性:
// 不优化的写法
void process(int arg1, int arg2, int arg3) {
// 处理逻辑
}
// 优化的写法
void process(int... args) {
// 处理逻辑
}
49. 使用条件运算符(三元运算符)简化代码:
// 不优化的写法
int result;
if (condition) {
result = 1;
} else {
result = 2;
}
// 优化的写法
int result = condition ? 1 : 2;
50. 使用内部类减少包级别的类可见性:
// 不优化的写法
package com.lfsun;
class InternalClass {
// 内部类
}
// 优化的写法
package com.lfsun;
public class OuterClass {
private class InternalClass {
// 内部类
}
}
51. 使用Arrays.fill填充数组元素:
// 不优化的写法
int[] array = new int[5];
for (int i = 0; i < array.length; i++) {
array[i] = 42;
}
// 优化的写法
int[] array = new int[5];
Arrays.fill(array, 42);
52. 使用System.arraycopy复制数组:
// 不优化的写法
int[] sourceArray = {1, 2, 3, 4, 5};
int[] targetArray = new int[sourceArray.length];
for (int i = 0; i < sourceArray.length; i++) {
targetArray[i] = sourceArray[i];
}
// 优化的写法
int[] sourceArray = {1, 2, 3, 4, 5};
int[] targetArray = new int[sourceArray.length];
System.arraycopy(sourceArray, 0, targetArray, 0, sourceArray.length);
使用 System.arraycopy
复制数组是一种更为高效的方式,相较于手动使用循环遍历的方式,它具有以下优势:
- 性能优化:
System.arraycopy
是由底层系统实现的本地方法,通常比手动的循环更为高效。这是因为底层系统可以针对具体的平台和硬件进行优化。 - 原子性:
System.arraycopy
是原子性的操作,意味着在数组复制的整个过程中,不会被其他线程中断,确保了复制的一致性。 - 简洁性: 使用
System.arraycopy
代码更为简洁,不需要手动编写循环,提高了代码的可读性和可维护性。
53. 使用List.subList获取子列表:
// 不优化的写法
List<String> list = Arrays.asList("A", "B", "C", "D", "E");
List<String> sublist = new ArrayList<>(list.subList(1, 4));
// 优化的写法
List<String> list = Arrays.asList("A", "B", "C", "D", "E");
List<String> sublist = list.subList(1, 4);
54. 使用Optional类避免空指针异常:
// 不优化的写法
String name = // 获取可能为null的值
if (name != null) {
System.out.println(name.length());
}
// 优化的写法
Optional<String> optionalName = Optional.ofNullable(name);
optionalName.ifPresent(n -> System.out.println(n.length()));
55. 使用ConcurrentHashMap提高并发性能:
// 不优化的写法
Map<String, Integer> myMap = new HashMap<>();
myMap.put("one", 1);
// 优化的写法
Map<String, Integer> myMap = new ConcurrentHashMap<>();
myMap.put("one", 1);
56. 使用Optional.orElseThrow替代自定义异常处理:
// 不优化的写法
Optional<String> value = Optional.ofNullable(getValue());
if (value.isPresent()) {
return value.get();
} else {
throw new CustomException("Value not found");
}
// 优化的写法
return Optional.ofNullable(getValue())
.orElseThrow(() -> new CustomException("Value not found"));
57. 使用方法引用简化代码:
// 不优化的写法
list.forEach(item -> System.out.println(item));
// 优化的写法
list.forEach(System.out::println);
58. 使用ThreadLocalRandom获取随机数:
// 不优化的写法
Random random = new Random();
int randomNumber = random.nextInt(100);
// 优化的写法
int randomNumber = ThreadLocalRandom.current().nextInt(100);
59. 使用Set接口的contains方法进行集合成员检查:
// 不优化的写法
List<String> list = Arrays.asList("Apple", "Banana", "Orange");
if (list.contains("Banana")) {
// 处理逻辑
}
// 优化的写法
Set<String> set = new HashSet<>(Arrays.asList("Apple", "Banana", "Orange"));
if (set.contains("Banana")) {
// 处理逻辑
}
60. 使用反射和动态代理提高代码灵活性:
// 不优化的写法
if (obj instanceof MyClass) {
((MyClass) obj).doSomething();
}
// 优化的写法
Method method = obj.getClass().getMethod("doSomething");
method.invoke(obj);
61. 使用默认方法接口提供默认实现
// 不优化的写法
interface MyInterface {
void doSomething();
}
class MyClass implements MyInterface {
@Override
public void doSomething() {
// 具体实现
}
}
// 优化的写法
interface MyInterface {
void doSomething();
default void doSomethingElse() {
// 默认实现
}
}
class MyClass implements MyInterface {
@Override
public void doSomething() {
// 具体实现
}
}
62. 使用新的日期和时间API:
// 不优化的写法
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
// 优化的写法
LocalDate currentDate = LocalDate.now();
int year = currentDate.getYear();
63. 使用Lambda表达式简化事件处理:
// 不优化的写法
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 处理事件
}
});
// 优化的写法
button.addActionListener(e -> {
// 处理事件
});
64. 使用Files.newBufferedWriter写入文本文件:
// 不优化的写法
try (PrintWriter writer = new PrintWriter(new FileWriter("file.txt"))) {
writer.println("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
// 优化的写法
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get("file.txt"))) {
writer.write("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
65. 使用静态工厂方法代替构造函数:
// 不优化的写法
MyObject obj = new MyObject();
// 优化的写法
MyObject obj = MyObject.create();
66. 避免在循环中创建匿名内部类:
// 不优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(new Consumer<String>() {
@Override
public void accept(String name) {
// 处理逻辑
}
});
// 优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> {
// 处理逻辑
});
67. 使用局部变量类型推断(var):
// 不优化的写法
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
// 优化的写法
var myMap = new HashMap<String, List<String>>();
68. 使用线程池提高线程利用率:
// 不优化的写法
Thread thread = new Thread(() -> {
// 线程执行的任务
});
thread.start();
// 优化的写法
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> {
// 线程执行的任务
});
69. 使用ClassLoader延迟加载类:
// 不优化的写法
Class<?> myClass = Class.forName("com.lfsun.MyClass");
MyClass instance = (MyClass) myClass.newInstance();
// 优化的写法
Class<?> myClass = ClassLoader.getSystemClassLoader().loadClass("com.lfsun.MyClass");
MyClass instance = (MyClass) myClass.getDeclaredConstructor().new
70. 使用Stream.distinct去除重复元素:
// 不优化的写法
List<String> myList = Arrays.asList("Apple", "Banana", "Apple", "Orange");
List<String> distinctList = new ArrayList<>(new HashSet<>(myList));
// 优化的写法
List<String> myList = Arrays.asList("Apple", "Banana", "Apple", "Orange");
List<String> distinctList = myList.stream().distinct().collect(Collectors.toList());
71. 使用String.format代替字符串连接:
// 不优化的写法
String result = "Hello, " + name + "!";
// 优化的写法
String result = String.format("Hello, %s!", name);
72. 使用IntStream和DoubleStream代替传统的循环:
// 不优化的写法
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
// 优化的写法
int sum = IntStream.rangeClosed(1, 100).sum();
73. 使用Atomic类提高原子性操作:
// 不优化的写法
int counter = 0;
counter++;
// 优化的写法
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet();
74. 使用StringJoiner拼接字符串:
// 不优化的写法
String result = "";
for (String s : list) {
result += s + ", ";
}
result = result.substring(0, result.length() - 2);
// 优化的写法
StringJoiner joiner = new StringJoiner(", ");
for (String s : list) {
joiner.add(s);
}
String result = joiner.toString();
75. 使用Arrays.copyOfRange代替手动数组复制:
// 不优化的写法
int[] source = {1, 2, 3, 4, 5};
int[] destination = new int[source.length];
System.arraycopy(source, 0, destination, 0, source.length);
// 优化的写法
int[] source = {1, 2, 3, 4, 5};
int[] destination = Arrays.copyOfRange(source, 0, source.length);
76. 使用Thread.join等待线程结束:
// 不优化的写法
Thread thread = new Thread(() -> {
// 线程执行逻辑
});
thread.start();
// 等待线程结束
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 优化的写法
Thread thread = new Thread(() -> {
// 线程执行逻辑
});
thread.start();
// 等待线程结束
thread.join();
77. 使用Files.lines读取文件内容:
// 不优化的写法
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
// 处理每行内容
}
} catch (IOException e) {
e.printStackTrace();
}
// 优化的写法
try {
Files.lines(Paths.get("file.txt")).forEach(line -> {
// 处理每行内容
});
} catch (IOException e) {
e.printStackTrace();
}
78. 使用ReentrantLock进行显式的锁定:
// 不优化的写法
synchronized (myObject) {
// 临界区
}
// 优化的写法
ReentrantLock lock = new ReentrantLock();
try {
lock.lock();
// 临界区
} finally {
lock.unlock();
}
79. 使用Map.compute方法简化Map操作:
// 不优化的写法
Map<String, Integer> map = new HashMap<>();
String key = "myKey";
if (map.containsKey(key)) {
map.put(key, map.get(key) + 1);
} else {
map.put(key, 1);
}
// 优化的写法
map.compute(key, (k, v) -> (v == null) ? 1 : v + 1);
80. 使用Objects.requireNonNull检查参数合法性:
// 不优化的写法
public void process(String data) {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null");
}
// 处理逻辑
}
// 优化的写法
public void process(String data) {
Objects.requireNonNull(data, "Data cannot be null");
// 处理逻辑
}
81. 使用Files.walk遍历文件目录:
// 不优化的写法
File folder = new File("/folder");
for (File file : folder.listFiles()) {
// 处理文件
}
// 优化的写法
Path folder = Paths.get("/folder");
try (Stream<Path> paths = Files.walk(folder)) {
paths.forEach(path -> {
// 处理文件
});
} catch (IOException e) {
e.printStackTrace();
}
82. 使用List的replaceAll方法更新所有元素:
// 不优化的写法
List<String> list = Arrays.asList("apple", "banana", "orange");
for (int i = 0; i < list.size(); i++) {
list.set(i, list.get(i).toUpperCase());
}
// 优化的写法
List<String> list = Arrays.asList("apple", "banana", "orange");
list.replaceAll(String::toUpperCase);
83. 使用CopyOnWriteArrayList提高并发性能:
// 不优化的写法
List<String> myList = new ArrayList<>();
myList.add("Apple");
myList.add("Banana");
myList.add("Orange");
// 优化的写法
List<String> myList = new CopyOnWriteArrayList<>();
myList.add("Apple");
myList.add("Banana");
myList.add("Orange");
84. 使用Map.merge简化Map操作:
// 不优化的写法
Map<String, Integer> map = new HashMap<>();
String key = "myKey";
if (map.containsKey(key)) {
map.put(key, map.get(key) + 1);
} else {
map.put(key, 1);
}
// 优化的写法
map.merge(key, 1, Integer::sum);
85. 使用Lambda表达式和Collectors进行集合操作:
// 不优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> uppercaseNames = new ArrayList<>();
for (String name : names) {
uppercaseNames.add(name.toUpperCase());
}
// 优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> uppercaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
86. 使用Optional解决嵌套的null检查:
// 不优化的写法
if (user != null) {
Address address = user.getAddress();
if (address != null) {
String city = address.getCity();
if (city != null) {
// 处理城市信息
}
}
}
// 优化的写法
Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.ifPresent(city -> {
// 处理城市信息
});
87. 使用java.time.Duration和Instant计算时间差:
// 不优化的写法
long startTime = System.currentTimeMillis();
// 执行一些操作
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
// 优化的写法
Instant start = Instant.now();
// 执行一些操作
Instant end = Instant.now();
Duration elapsedTime = Duration.between(start, end);
88. 使用java.nio.file.Path代替字符串操作路径:
// 不优化的写法
String filePath = "/file.txt";
File file = new File(filePath);
// 优化的写法
Path filePath = Paths.get("/file.txt");
89. 使用String.isBlank判断字符串是否为空或只包含空白字符:
// 不优化的写法
if (str != null && !str.trim().isEmpty()) {
// 处理非空字符串逻辑
}
// 优化的写法
if (str != null && !str.isBlank()) {
// 处理非空字符串逻辑
}
90. 使用Map.computeIfAbsent进行延迟初始化:
// 不优化的写法
Map<String, List<String>> map = new HashMap<>();
if (!map.containsKey("key")) {
map.put("key", new ArrayList<>());
}
map.get("key").add("value");
// 优化的写法
Map<String, List<String>> map = new HashMap<>();
map.computeIfAbsent("key", k -> new ArrayList<>()).add("value");
91. 使用Objects.equals避免空指针异常:
// 不优化的写法
boolean isEqual = (obj1 != null) ? obj1.equals(obj2) : (obj2 == null);
// 优化的写法
boolean isEqual = Objects.equals(obj1, obj2);
92. 使用Math.floorDiv和Math.floorMod代替传统除法和取模运算:
// 不优化的写法
int quotient = a / b;
int remainder = a % b;
// 优化的写法
int quotient = Math.floorDiv(a, b);
int remainder = Math.floorMod(a, b);
93. 使用ClassLoader.getSystemResourceAsStream加载类路径下的资源文件:
// 不优化的写法
InputStream stream = getClass().getClassLoader().getResourceAsStream("config.properties");
// 优化的写法
InputStream stream = ClassLoader.getSystemResourceAsStream("config.properties");
使用 ClassLoader.getSystemResourceAsStream
加载类路径下的资源文件是一种更为推荐的做法,相较于 getClass().getClassLoader().getResourceAsStream
,它具有以下优势:
- 更简洁:
ClassLoader.getSystemResourceAsStream
的调用更为简洁,不需要通过获取类加载器再获取资源流。 - 避免空指针异常:
ClassLoader.getSystemResourceAsStream
不会返回null
,而是会抛出NullPointerException
,这有助于在资源不存在时更早地发现问题。 - 全局资源访问:
ClassLoader.getSystemResourceAsStream
使用系统类加载器,可以用于访问应用程序类路径下的资源,而不仅限于当前类的类路径。
94. 使用String.repeat重复字符串:
// 不优化的写法
String repeated = "";
for (int i = 0; i < n; i++) {
repeated += "abc";
}
// 优化的写法
String repeated = "abc".repeat(n);
95. 使用List.copyOf创建不可变集合:
// 不优化的写法
List<String> originalList = Arrays.asList("a", "b", "c");
List<String> immutableList = Collections.unmodifiableList(new ArrayList<>(originalList));
// 优化的写法
List<String> immutableList = List.copyOf(originalList);
96. 使用Stream的anyMatch和noneMatch简化集合元素匹配:
// 不优化的写法
boolean contains = false;
for (String element : list) {
if (element.equals("target")) {
contains = true;
break;
}
}
// 优化的写法
boolean contains = list.stream().anyMatch(element -> element.equals("target"));
97. 使用File.toPath将File对象转换为Path对象:
// 不优化的写法
File file = new File("lfsun.txt");
Path path = file.toPath();
// 优化的写法
Path path = Paths.get("lfsun.txt");
98. 使用FileSystems.getDefault获取默认文件系统:
// 不优化的写法
Path path = Paths.get("lfsun.txt");
// 优化的写法
Path path = FileSystems.getDefault().getPath("lfsun.txt");
使用 FileSystems.getDefault().getPath
获取默认文件系统的路径是一种更为推荐的做法,相较于 Paths.get
,它具有以下优势:
- 更灵活:
FileSystems.getDefault().getPath
可以提供更多的灵活性,允许在获取路径时指定文件系统的一些属性。例如,可以使用不同的文件系统,提供自定义的文件系统属性等。 - 统一风格: 使用
FileSystems.getDefault().getPath
统一了获取路径的方式,使得代码更具一致性。这有助于提高代码的可读性和可维护性。
99. 使用Collections.newSetFromMap创建基于Map的Set:
// 不优化的写法
Map<String, Boolean> map = new ConcurrentHashMap<>();
Set<String> set = map.keySet();
// 优化的写法
Set<String> set = Collections.newSetFromMap(new ConcurrentHashMap<>());
使用 Collections.newSetFromMap
创建基于 Map
的 Set
是一种更为推荐的做法,相较于直接使用 map.keySet()
,它具有以下优势:
- 线程安全性: 使用
Collections.newSetFromMap
创建的Set
是线程安全的,底层使用的是传入的ConcurrentMap
,因此适用于多线程环境。 - 不可变性: 通过
Collections.newSetFromMap
创建的Set
是不可变的,不能通过add
、remove
等方法修改其内容。这有助于确保数据的一致性。 - 灵活性: 可以通过传入不同类型的
Map
实现,以创建不同类型的Set
。例如,可以传入HashMap
、TreeMap
等。
100. 使用List.sort进行列表排序:
// 不优化的写法
List<String> list = Arrays.asList("c", "a", "b");
Collections.sort(list);
// 优化的写法
List<String> list = Arrays.asList("c", "a", "b");
list.sort(Comparator.naturalOrder());
使用 List.sort
进行列表排序是一种更为推荐的做法,相较于 Collections.sort
,它具有以下优势:
- 更直接:
list.sort()
方法是List
接口的默认方法,使得排序操作更加直接和一致。不需要通过Collections
类来调用排序方法。 - 更灵活:
list.sort()
方法可以接受一个Comparator
参数,使得排序更加灵活。通过Comparator
,可以实现自定义的排序规则,而不仅限于自然排序。 - 支持流式操作:
list.sort()
方法可以很方便地与流式操作一起使用,如使用Comparator
和thenComparing
进行复杂排序。
101. 使用Path.resolve解析路径:
// 不优化的写法
Path path1 = Paths.get("");
Path path2 = Paths.get("file.txt");
Path fullPath = Paths.get(path1.toString(), path2.toString());
// 优化的写法
Path path1 = Paths.get("");
Path path2 = Paths.get("file.txt");
Path fullPath = path1.resolve(path2);
102. 使用Stream.collect(Collectors.joining)拼接字符串:
// 不优化的写法
List<String> words = Arrays.asList("Hello", "World", "Java");
String result = words.stream().reduce("", (s1, s2) -> s1 + s2);
// 优化的写法
List<String> words = Arrays.asList("Hello", "World", "Java");
String result = words.stream().collect(Collectors.joining());
103. 使用Pattern和Matcher进行正则表达式匹配:
// 不优化的写法
String text = "The quick brown fox";
boolean containsFox = text.matches(".*fox.*");
// 优化的写法
Pattern pattern = Pattern.compile(".*fox.*");
Matcher matcher = pattern.matcher("The quick brown fox");
boolean containsFox = matcher.matches();
104. 使用Files.isRegularFile检查文件是否为普通文件:
// 不优化的写法
Path path = Paths.get("file.txt");
if (Files.exists(path) && Files.isRegularFile(path)) {
// 处理文件逻辑
}
// 优化的写法
Path path = Paths.get("file.txt");
if (Files.isRegularFile(path)) {
// 处理文件逻辑
}
105. 使用Optional避免空指针异常:
// 不优化的写法
String result = null;
if (value != null) {
result = value.toString();
}
// 优化的写法
String result = Optional.ofNullable(value)
.map(Object::toString)
.orElse(null);
106. 使用Lambda表达式简化Comparator的创建:
// 不优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort(new Comparator<String>() {
@Override
public int compare(String name1, String name2) {
return name1.compareTo(name2);
}
});
// 优化的写法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort((name1, name2) -> name1.compareTo(name2));
107. 使用Optional.map和Optional.filter链式操作:
// 不优化的写法
Optional<String> result = Optional.ofNullable(getValue());
if (result.isPresent()) {
String uppercased = result.get().toUpperCase();
if (uppercased.length() > 5) {
System.out.println(uppercased);
}
}
// 优化的写法
Optional.ofNullable(getValue())
.map(String::toUpperCase)
.filter(s -> s.length() > 5)
.ifPresent(System.out::println);
108. 使用Collectors.joining拼接字符串:
// 不优化的写法
List<String> list = Arrays.asList("Apple", "Banana", "Orange");
String result = "";
for (String item : list) {
result += item + ", ";
}
result = result.isEmpty() ? result : result.substring(0, result.length() - 2);
// 优化的写法
List<String> list = Arrays.asList("Apple", "Banana", "Orange");
String result = list.stream().collect(Collectors.joining(", "));
109. 使用Arrays.asList创建不可变集合:
// 不优化的写法
List<String> myList = new ArrayList<>();
myList.add("Apple");
myList.add("Banana");
myList.add("Orange");
myList = Collections.unmodifiableList(myList);
// 优化的写法
List<String> myList = Arrays.asList("Apple", "Banana", "Orange");
110. 使用Comparator.comparing简化比较器的创建:
// 不优化的写法
List<Person> people = Arrays.asList(new Person("Alice", 25), new Person("Bob", 30));
people.sort(new Comparator<Person>() {
@Override
public int compare(Person person1, Person person2) {
return Integer.compare(person1.getAge(), person2.getAge());
}
});
// 优化的写法
List<Person> people = Arrays.asList(new Person("Alice", 25), new Person("Bob", 30));
people.sort(Comparator.comparing(Person::getAge));
111. 使用StringTokenizer代替String的split方法:
// 不优化的写法
String[] tokens = "apple,orange,banana".split(",");
// 优化的写法
StringTokenizer tokenizer = new StringTokenizer("apple,orange,banana", ",");
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
// 处理每个token
}
使用 StringTokenizer
代替 String
的 split
方法是一种优化的方式,尤其是在需要逐个处理分隔符分割的字符串时。StringTokenizer
提供了更多的灵活性和控制,相较于 split
方法,它具有以下优势:
- 逐个处理:
StringTokenizer
允许逐个处理每个分隔符分割的字符串。这对于在处理每个 token 时执行特定操作的情况非常有用。 - 更多控制选项:
StringTokenizer
允许你指定多个分隔符,并且提供了更多的控制选项,例如是否返回分隔符。 - 不使用正则表达式:
StringTokenizer
不依赖于正则表达式,因此在某些情况下可能比split
更快。
112. 使用Runtime.getRuntime().availableProcessors()获取处理器核心数:
int processors = Runtime.getRuntime().availableProcessors();
113. 使用Arrays.copyOf代替手动数组复制:
// 不优化的写法
int[] source = {1, 2, 3, 4, 5};
int[] destination = new int[source.length];
System.arraycopy(source, 0, destination, 0, source.length);
// 优化的写法
int[] source = {1, 2, 3, 4, 5};
int[] destination = Arrays.copyOf(source, source.length);
114. 使用LinkedHashMap保持插入顺序:
// 不优化的写法
Map<String, Integer> map = new HashMap<>();
map.put("one", 1);
map.put("three", 3);
map.put("two", 2);
// 优化的写法
Map<String, Integer> map = new LinkedHashMap<>();
map.put("one", 1);
map.put("three", 3);
map.put("two", 2);
115. 使用System.arraycopy进行数组复制:
// 不优化的写法
int[] source = {1, 2, 3, 4, 5};
int[] destination = new int[source.length];
for (int i = 0; i < source.length; i++) {
destination[i] = source[i];
}
// 优化的写法
int[] source = {1, 2, 3, 4, 5};
int[] destination = new int[source.length];
System.arraycopy(source, 0, destination, 0, source.length);
116. 使用Files.newInputStream和Files.newOutputStream操作文件流:
// 不优化的写法
InputStream inputStream = new FileInputStream("input.txt");
OutputStream outputStream = new FileOutputStream("output.txt");
// 优化的写法
InputStream inputStream = Files.newInputStream(Paths.get("input.txt"));
OutputStream outputStream = Files.newOutputStream(Paths.get("output.txt"));
使用 Files.newInputStream
和 Files.newOutputStream
操作文件流是一种更为现代、灵活且推荐的方式,相较于传统的 FileInputStream
和 FileOutputStream
,它具有以下优势:
- 更直观的路径处理: 使用
Paths.get("input.txt")
来构建路径更为直观和灵活,可以处理相对路径和绝对路径。 - 更丰富的异常处理:
Files.newInputStream
和Files.newOutputStream
可以抛出更丰富的异常,使得对文件操作的错误更容易排查。 - 更灵活的配置选项:
Files.newInputStream
和Files.newOutputStream
支持一些配置选项,例如StandardOpenOption
,可以更灵活地配置文件的打开方式。
117. 使用Files.exists判断文件是否存在:
// 不优化的写法
File file = new File("lfsun.txt");
if (file.exists()) {
// 文件存在逻辑
}
// 优化的写法
if (Files.exists(Paths.get("lfsun.txt"))) {
// 文件存在逻辑
}
118. 使用Files.createFile创建文件:
// 不优化的写法
File file = new File("lfsun.txt");
if (!file.exists()) {
file.createNewFile();
}
// 优化的写法
Files.createFile(Paths.get("lfsun.txt"));
使用 Files.createFile
创建文件是一种更为现代和推荐的方式,相较于传统的 File
类的方式,它具有以下优势:
- 更直观的路径处理: 使用
Paths.get("lfsun.txt")
来构建路径更为直观和灵活,可以处理相对路径和绝对路径。 - 更丰富的异常处理:
Files.createFile
可以抛出更丰富的异常,使得对文件创建的错误更容易排查。 - 原子性操作:
Files.createFile
是一个原子性的操作,如果文件已经存在,则会抛出FileAlreadyExistsException
,避免了在检查文件存在性和创建文件之间的竞态条件。
119. 使用Files.delete删除文件:
// 不优化的写法
File file = new File("lfsun.txt");
if (file.exists()) {
file.delete();
}
// 优化的写法
Files.deleteIfExists(Paths.get("lfsun.txt"));
120. 使用Files.walkFileTree遍历文件树:
// 不优化的写法
FileVisitor<Path> fileVisitor = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// 处理文件逻辑
return FileVisitResult.CONTINUE;
}
};
Files.walkFileTree(Paths.get("/directory"), fileVisitor);
// 优化的写法
Files.walkFileTree(Paths.get("/directory"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// 处理文件逻辑
return FileVisitResult.CONTINUE;
}
});
121. 使用Files.createDirectory创建单级目录:
// 不优化的写法
File file = new File("/directory");
if (!file.exists()) {
file.mkdirs();
}
// 优化的写法
Files.createDirectory(Paths.get("/directory"));
122. 使用Files.createDirectories创建多级目录:
// 不优化的写法
File file = new File("/multiple/levels");
if (!file.exists()) {
file.mkdirs();
}
// 优化的写法
Files.createDirectories(Paths.get("/multiple/levels"));
123. 使用Files.copy复制文件:
// 不优化的写法
Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");
Files.write(target, Files.readAllBytes(source));
// 优化的写法
Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
124. 使用Files.isSameFile检查两个文件是否相同:
// 不优化的写法
Path file1 = Paths.get("file1.txt");
Path file2 = Paths.get("file2.txt");
if (Files.exists(file1) && Files.exists(file2) && Files.isRegularFile(file1) && Files.isRegularFile(file2)) {
boolean areSame = Files.isSameFile(file1, file2);
// 处理相同文件逻辑
}
// 优化的写法
Path file1 = Paths.get("file1.txt");
Path file2 = Paths.get("file2.txt");
if (Files.isRegularFile(file1) && Files.isRegularFile(file2)) {
boolean areSame = Files.isSameFile(file1, file2);
// 处理相同文件逻辑
}
125. 使用Files.getLastModifiedTime获取文件最后修改时间:
Path filePath = Paths.get("file.txt");
if (Files.exists(filePath)) {
long lastModifiedTime = Files.getLastModifiedTime(filePath).toMillis();
// 处理最后修改时间逻辑
}
126. 使用Files.size获取文件大小:
Path filePath = Paths.get("file.txt");
if (Files.exists(filePath)) {
long fileSize = Files.size(filePath);
// 处理文件大小逻辑
}
127. 使用Files.readAttributes获取文件属性:
Path filePath = Paths.get("file.txt");
if (Files.exists(filePath)) {
BasicFileAttributes attributes = Files.readAttributes(filePath, BasicFileAttributes.class);
FileTime creationTime = attributes.creationTime();
// 处理文件属性逻辑
}
128. 使用Files.probeContentType获取文件内容类型:
Path filePath = Paths.get("file.txt");
String contentType = Files.probeContentType(filePath);
129. 使用Files.isSymbolicLink检查文件是否为符号链接:
// 不优化的写法
Path filePath = Paths.get("file.txt");
if (Files.exists(filePath) && Files.isSymbolicLink(filePath)) {
// 处理符号链接逻辑
}
// 优化的写法
Path filePath = Paths.get("file.txt");
if (Files.isSymbolicLink(filePath)) {
// 处理符号链接逻辑
}
130. 使用Files.isReadable检查文件是否可读:
// 不优化的写法
Path filePath = Paths.get("file.txt");
if (Files.exists(filePath) && Files.isReadable(filePath)) {
// 处理可读文件逻辑
}
// 优化的写法
Path filePath = Paths.get("file.txt");
if (Files.isReadable(filePath)) {
// 处理可读文件逻辑
}
131. 使用Files.isWritable检查文件是否可写:
// 不优化的写法
Path filePath = Paths.get("file.txt");
if (Files.exists(filePath) && Files.isWritable(filePath)) {
// 处理可写文件逻辑
}
// 优化的写法
Path filePath = Paths.get("file.txt");
if (Files.isWritable(filePath)) {
// 处理可写文件逻辑
}
132. 使用Files.getAttribute获取文件属性:
Path filePath = Paths.get("file.txt");
if (Files.exists(filePath)) {
Object attribute = Files.getAttribute(filePath, "basic:creationTime");
// 处理文件属性逻辑
}
133. 使用Files.setAttribute设置文件属性:
Path filePath = Paths.get("file.txt");
if (Files.exists(filePath)) {
Files.setAttribute(filePath, "basic:creationTime", FileTime.from(Instant.now()));
}
134. 使用Files.isExecutable检查文件是否可执行:
// 不优化的写法
Path filePath = Paths.get("script.sh");
if (Files.exists(filePath) && Files.isExecutable(filePath)) {
// 处理可执行文件逻辑
}
// 优化的写法
Path filePath = Paths.get("script.sh");
if (Files.isExecutable(filePath)) {
// 处理可执行文件逻辑
}
135. 使用Files.newBufferedReader读取文本文件:
try (BufferedReader reader = Files.newBufferedReader(Paths.get("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
// 处理每行内容
}
} catch (IOException e) {
e.printStackTrace();
}
136.使用DateTimeFormatter替代SimpleDateFormat:
// 不优化的写法
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formattedDate = sdf.format(new Date());
// 优化的写法
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDate = LocalDateTime.now().format(formatter);
137. 使用LocalDate和LocalTime代替Date和Calendar:
// 不优化的写法
Date currentDate = new Date();
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
// 优化的写法
LocalDate currentDate = LocalDate.now();
int year = currentDate.getYear();
138. 使用Optional的map和flatMap进行链式操作:
// 不优化的写法
Optional<String> result = Optional.of("Hello");
if (result.isPresent()) {
String uppercased = result.get().toUpperCase();
Optional<String> finalResult = Optional.of(uppercased);
}
// 优化的写法
Optional<String> result = Optional.of("Hello");
Optional<String> finalResult = result.map(String::toUpperCase);