👉 写代码时,总记不住 String 的 substring() 是左闭右开还是左闭右闭?
👉 想格式化日期,结果 SimpleDateFormat 一用多线程就出 bug?
👉 面试官问:“说说 Java 常用类?” 你脑子里闪过 String、Math,但说不完整,更别说原理了……
java.lang.String:字符串王者char[] 存储(Java 9+ 用 byte[] 优化)String a = "hello";
String b = "hello";
System.out.println(a == b); // true(常量池)方法 | 作用 | 注意 |
|---|---|---|
length() | 返回长度 | - |
charAt(int) | 获取指定位置字符 | 索引从 0 开始 |
substring(int, int) | 截取子串 | 左闭右开!substring(0,3) 取 0,1,2 |
indexOf(String) | 查找子串位置 | 找不到返回 -1 |
startsWith() / endsWith() | 判断前缀/后缀 | - |
trim() | 去除首尾空格 | - |
toUpperCase() / toLowerCase() | 大小写转换 | - |
split(String) | 分割字符串 | 返回 String[] |
replace(old, new) | 替换字符/串 | 返回新字符串 |
// 错误:频繁修改,创建大量中间对象
String s = "";
for (int i = 0; i < 1000; i++) {
s += i; // 每次都 new String()
}
// 正确:用 StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String result = sb.toString();✅ 结论:循环拼接用
StringBuilder,单次操作用+也可。
java.lang.StringBuilder & StringBuffer类 | 线程安全 | 性能 | 使用场景 |
|---|---|---|---|
StringBuilder | ❌ 不安全 | ⚡️ 高 | 单线程(推荐) |
StringBuffer | ✅ 安全 | 🔼 稍低 | 多线程(极少用) |
StringBuilder sb = new StringBuilder("Hello");
sb.append(" ").append("World"); // 链式调用
sb.insert(5, " Java"); // Hello Java World
sb.delete(0, 5); // 删除 [0,5)
System.out.println(sb); // 输出: Java World💡 建议:99% 场景用
StringBuilder。
java.util.List:有序可重复集合ArrayList:动态数组O(1)),增删慢(O(n),涉及移动)Object[],自动扩容(1.5倍)List<String> list = new ArrayList<>();
list.add("A");
list.add(1, "B"); // 插入
String first = list.get(0); // 查询
list.remove("A"); // 删除LinkedList:双向链表O(1),已知节点),查询慢(O(n))Deque,可作队列/栈List<String> list = new LinkedList<>();
((LinkedList<String>) list).addFirst("A"); // 头插
((LinkedList<String>) list).addLast("B"); // 尾插✅ 选型建议:
ArrayListLinkedListjava.util.Map:键值对集合HashMap:最常用Map<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);
Integer age = map.get("Alice"); // 获取
boolean hasKey = map.containsKey("Bob");
map.remove("Alice");LinkedHashMap:有序 HashMap// 按访问顺序排序(最近访问的放最后)
Map<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true);TreeMap:有序 MapMap<String, Integer> map = new TreeMap<>(); // 按 key 字典序排序ConcurrentHashMap:线程安全 MapConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("count", 1);
map.get("count");✅ 选型建议:
HashMapLinkedHashMap 或 TreeMapConcurrentHashMapjava.util.Date & java.time:日期时间处理Date:可读性差,方法过时SimpleDateFormat:非线程安全!多线程共享会出错// ❌ 危险!多线程下可能抛异常或解析错误
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// ✅ 正确:每次新建,或用 ThreadLocal,或用 DateTimeFormatter在 java.time 包中:
类 | 用途 |
|---|---|
LocalDateTime | 日期 + 时间(无时区) |
LocalDate | 仅日期 |
LocalTime | 仅时间 |
ZonedDateTime | 带时区的日期时间 |
Duration | 时间段(秒、纳秒) |
Period | 日期段(年、月、日) |
DateTimeFormatter | 格式化工具(线程安全) |
// 当前时间
LocalDateTime now = LocalDateTime.now();
// 解析字符串
LocalDateTime dt = LocalDateTime.parse("2025-08-13T10:30:00");
// 格式化
String str = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm"));
// 计算
LocalDateTime tomorrow = now.plusDays(1);
Duration duration = Duration.between(now, tomorrow);✅ 结论:新项目一律用
java.time,安全、清晰、功能强。
java.math:精确计算BigInteger:大整数BigInteger a = new BigInteger("12345678901234567890");
BigInteger b = new BigInteger("98765432109876543210");
BigInteger sum = a.add(b); // 加法BigDecimal:高精度浮点数(金融首选!)BigDecimal price = new BigDecimal("19.9");
BigDecimal tax = new BigDecimal("0.05");
BigDecimal total = price.multiply(tax.add(BigDecimal.ONE));
// 保留2位小数,四舍五入
total = total.setScale(2, RoundingMode.HALF_UP);⚠️ 绝对不要用 double 做金钱计算!
System.out.println(0.1 + 0.2); // 输出 0.30000000000000004!java.util.Objects:空值工具类String name = null;
// 判空(比 == null 更优雅)
boolean isNull = Objects.isNull(name);
boolean nonNull = Objects.nonNull(name);
// 防空指针(常用)
String displayName = Objects.requireNonNull(name, "名字不能为空");
// 生成 hashCode(处理 null)
int hash = Objects.hash(name, age);
// 比较(处理 null)
int cmp = Objects.compare("a", "b", String::compareTo);String 为什么设计成不可变的?答:
hashCode() 只计算一次,提升性能;ArrayList 扩容机制是怎样的?答:
Arrays.copyOf() 复制数据;HashMap 的底层原理?答: JDK 8+:
hash(key) 计算桶位置;BigDecimal 为什么能精确计算?答: 它把浮点数拆成 unscaledValue(BigInteger) 和 scale(小数位数)。 比如
19.9存储为199和scale=1,所有计算基于整数,避免了二进制浮点数的精度丢失问题。
需求 | 推荐类 | 关键点 |
|---|---|---|
字符串操作 | String + StringBuilder | String 不可变,拼接用 StringBuilder |
有序集合 | ArrayList | 查询多用它,注意初始化容量 |
键值存储 | HashMap / ConcurrentHashMap | 普通用前者,并发用后者 |
日期时间 | java.time.LocalDateTime | 线程安全,API 清晰 |
金钱计算 | BigDecimal | 绝对不用 double! |
判空工具 | Objects | requireNonNull 防空指针 |
Java 常用类不是“语法糖”,而是“生产力工具”。 从
String的不可变性,到ConcurrentHashMap的高并发设计, 每一个类背后都是对性能、安全、易用性的深度权衡。 掌握它们,你才能写出高效、健壮、专业的 Java 代码!
希望这篇能帮你系统掌握 Java 常用类!