1. Java常用类概述
在Java开发中,常用类就像是我们日常生活中的"工具箱",里面装满了各种解决特定问题的工具。这些类被精心设计并封装在Java标准库中,开发者可以直接调用而无需重复造轮子。掌握这些常用类不仅能提高编码效率,更能写出更健壮、更优雅的代码。
我见过太多初学者因为对这些基础类掌握不牢,导致代码冗长且容易出错。比如用"+"拼接大量字符串,或者自己实现日期计算等。实际上,Java已经为我们准备了StringBuilder、LocalDateTime等现成的解决方案。本文将带你系统梳理Java中最核心的常用类,分享我在实际项目中的使用心得。
2. 字符串处理类
2.1 String类
String是Java中最常用的类之一,但它的特殊性常常被忽视。首先,String是不可变的(immutable),这意味着每次"修改"字符串实际上都是创建新对象。例如:
String str = "hello"; str += " world"; // 实际上新建了一个String对象这种特性带来几个重要影响:
- 频繁修改字符串会导致大量临时对象,影响性能
- 字符串常量池可以复用相同的字符串字面量
- 线程安全,因为状态不可变
提示:在需要频繁修改字符串的场景,应该使用StringBuilder或StringBuffer
String的常用方法包括:
length():获取长度charAt(int):获取指定位置字符substring(int):截取子串indexOf(String):查找子串位置equals(Object):比较内容(不要用==比较字符串内容)
2.2 StringBuilder与StringBuffer
这两个类专门用于处理可变字符串,解决了String在频繁修改时的性能问题。它们的API几乎完全相同,主要区别在于:
| 特性 | StringBuilder | StringBuffer |
|---|---|---|
| 线程安全 | 否 | 是 |
| 性能 | 更高 | 稍低 |
| 适用场景 | 单线程 | 多线程 |
基本用法示例:
StringBuilder sb = new StringBuilder(); sb.append("Hello").append(" ").append("World"); String result = sb.toString(); // "Hello World"经验:在明确单线程环境下,优先使用StringBuilder。我曾在高并发日志处理中使用StringBuffer,避免了线程安全问题。
3. 集合框架类
3.1 List接口及其实现类
List代表有序、可重复的集合,最常用的实现有:
ArrayList:
- 基于动态数组实现
- 随机访问快(O(1)),中间插入/删除慢(O(n))
- 初始容量10,扩容1.5倍
LinkedList:
- 基于双向链表实现
- 插入删除快(O(1)),随机访问慢(O(n))
- 实现了Deque接口,可用作队列
选择建议:
- 查询多、修改少 → ArrayList
- 频繁在首尾增删 → LinkedList
3.2 Map接口及其实现类
Map存储键值对,常用实现:
HashMap:
- 基于哈希表,无序
- 允许null键/值
- 线程不安全
- Java8后链表长度>8转红黑树
LinkedHashMap:
- 保持插入顺序或访问顺序
- 可用于实现LRU缓存
TreeMap:
- 基于红黑树,按键排序
- 支持范围查询
踩坑记录:我曾误用HashMap存储有序数据,结果发现遍历顺序与插入顺序不一致,后来改用LinkedHashMap解决问题。
4. 日期时间类
4.1 旧版Date/Calendar的问题
Java8之前的日期API存在诸多问题:
- Date既包含日期又包含时间,设计混乱
- Calendar操作繁琐,月份从0开始
- 线程安全问题
- 难以进行日期计算
4.2 Java8新日期API
Java8引入了全新的java.time包:
LocalDate:只包含日期
LocalDate today = LocalDate.now(); LocalDate birthday = LocalDate.of(1990, Month.JANUARY, 1);LocalTime:只包含时间
LocalTime now = LocalTime.now(); LocalTime noon = LocalTime.of(12, 0);LocalDateTime:日期+时间
LocalDateTime ldt = LocalDateTime.now();Duration/Period:时间间隔
Duration between = Duration.between(startTime, endTime);DateTimeFormatter:格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formatted = ldt.format(formatter);
建议:新项目应全部使用java.time API,旧代码逐步迁移。我在处理国际航班时间转换时,新API的时区支持(ZonedDateTime)帮了大忙。
5. 包装类与自动装箱
Java为每个基本类型提供了对应的包装类:
| 基本类型 | 包装类 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
自动装箱/拆箱是Java5引入的特性:
Integer i = 10; // 自动装箱 (int -> Integer) int n = i; // 自动拆箱 (Integer -> int)注意事项:
- 包装类对象比较应该用equals(),而非==
- 自动装箱有性能开销,在循环中需注意
- 缓存机制:Integer缓存-128~127的对象
6. 数学运算类
6.1 Math类
Math提供各种数学运算的静态方法:
- 基本运算:abs(), max(), min()
- 指数对数:exp(), log(), pow()
- 三角函数:sin(), cos(), tan()
- 舍入:round(), ceil(), floor()
- 随机数:random() [0.0,1.0)
6.2 Random类
生成伪随机数,比Math.random()更灵活:
Random random = new Random(); int num = random.nextInt(100); // 0-99的随机数技巧:在需要可重复的随机序列时,使用固定种子:
Random random = new Random(12345L); // 固定种子
7. 系统相关类
7.1 System类
提供系统级操作:
- 标准输入输出:in, out, err
- 系统属性:getProperty()
- 垃圾回收:gc()
- 退出程序:exit()
7.2 Runtime类
获取运行时环境信息:
- 可用处理器:availableProcessors()
- 内存情况:totalMemory(), freeMemory()
- 执行外部命令:exec()
示例:获取JVM内存信息
Runtime runtime = Runtime.getRuntime(); long total = runtime.totalMemory(); long free = runtime.freeMemory(); long used = total - free;8. 文件IO类
8.1 File类
代表文件或目录路径(非文件内容):
File file = new File("test.txt"); boolean exists = file.exists(); long size = file.length(); boolean success = file.delete();8.2 新的NIO.2 API
Java7引入了更强大的Files和Paths工具类:
Path path = Paths.get("data.txt"); byte[] bytes = Files.readAllBytes(path); List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8); Files.write(path, content.getBytes());优势:
- 更简洁的API
- 更好的异常处理
- 支持符号链接
- 文件属性操作
9. 异常处理类
Java异常体系:
Throwable ├── Error (系统错误,通常不处理) └── Exception ├── RuntimeException (未检查异常) └── 其他Exception (检查异常)常用异常类:
- NullPointerException
- ArrayIndexOutOfBoundsException
- IOException
- ClassNotFoundException
最佳实践:不要捕获Throwable或Error;自定义异常应提供有意义的构造方法;在日志中包含上下文信息。
10. 工具类总结
10.1 Objects
Java7引入的工具类,提供:
- 空安全比较:equals()
- 空检查:requireNonNull()
- 哈希计算:hash()
10.2 Arrays
数组工具类:
- 排序:sort()
- 二分查找:binarySearch()
- 填充:fill()
- 转列表:asList()
10.3 Collections
集合工具类:
- 排序:sort()
- 反转:reverse()
- 线程安全包装:synchronizedXXX()
- 不可变集合:unmodifiableXXX()
11. 实际应用经验
字符串拼接:
- 少量拼接:直接使用+
- 循环内拼接:必须用StringBuilder
- 已知最终大小:预设StringBuilder容量
集合初始化:
- 预估大小:new ArrayList<>(initialCapacity)
- 不可变集合:List.of(), Set.of() (Java9+)
日期处理:
- 持久化:使用Instant
- 显示:使用ZonedDateTime+DateTimeFormatter
- 计算:使用Period/Duration
性能优化:
- 避免自动装箱循环
- 重用Random实例
- 合理选择集合实现
代码可读性:
- 使用静态导入Math方法
- 用枚举代替常量
- 使用try-with-resources处理IO
12. 常见问题排查
字符串比较出错:
- 症状:==比较返回false
- 原因:比较的是对象而非内容
- 解决:使用equals()方法
ConcurrentModificationException:
- 症状:遍历时修改集合
- 解决:使用迭代器的remove()或复制集合
NumberFormatException:
- 症状:字符串转数字失败
- 解决:先检查isNumber()或捕获异常
内存泄漏:
- 症状:集合持有对象导致无法GC
- 解决:使用WeakHashMap或及时清理
时区问题:
- 症状:显示时间与预期不符
- 解决:明确指定时区处理
13. 高级技巧
方法引用:
list.forEach(System.out::println);Optional避免NPE:
Optional.ofNullable(str).ifPresent(System.out::println);Stream操作集合:
list.stream().filter(s -> s.length()>3).sorted().collect(Collectors.toList());自定义不可变类:
- final类
- final字段
- 深度拷贝可变对象
对象池技术:
- 重用昂贵对象
- 如数据库连接池
掌握这些常用类后,我最大的体会是:好的Java开发者不仅要会使用这些工具,更要理解它们的设计意图和适用场景。比如知道为什么String要设计为不可变,HashMap如何解决哈希冲突等。这种深层次的理解能帮助我们在实际开发中做出更合理的选择。