Java 核心基础进阶:从字符串操作到容器框架的深度解析

📅 2026/7/2 19:57:17 👁️ 阅读次数 📝 编程学习
Java 核心基础进阶:从字符串操作到容器框架的深度解析

一、字符串的“变身”艺术:StringBuffer 与 StringBuilder

我们在初学 Java 时知道  String 是不可变的。这意味着每次对 String 进行修改(如拼接),实际上都会在内存中创建一个新的对象。如果在循环中进行大量拼接,性能损耗是巨大的。

故可变字符串类出现了:

StringBuffer:它是线程安全的。如果你查看源码,会发现它的方法大多加了  synchronized  关键字。这就像是一个“带锁的笔记本”,多人同时写也不会乱,但效率相对较低。
StringBuilder:它是线程不安全的。去掉了同步锁,就像一本“敞开的笔记本”,写入速度极快。

💡 经验法则:

如果是在单线程环境下进行大量字符串拼接(比如构建 SQL 语句、拼接 HTML),首选  StringBuilder 。
只有在多线程共享同一个字符串缓冲区时,才考虑使用  StringBuffer 。

二、精准控制:DecimalFormat 小数格式化

在处理金融数据或报表展示时,我们经常需要对数字进行格式化。 DecimalFormat 是一个非常强大的工具类。

通过定义模式(Pattern),我们可以轻松控制小数的位数:

"#.00" :表示保留两位小数,不足补零。
 "#,###.##" :表示千分位分隔,且最多保留两位小数。

三、Java 容器家族概览

Java 的集合框架主要分为两大类i:Collection 和 Map。

Collection 接口:这是单列数据的根接口,下面主要衍生出  List (列表)和  Set (集合)。
Map 接口:这是双列数据的根接口,用于存储键值对(Key-Value)。

  1. List 接口:有序的队列

List  的特点是有序且可重复。你可以把它想象成一排编了号的储物柜。

ArrayList vs LinkedList

ArrayList(数组实现):

结构:底层是动态数组。
优势:随机访问速度快。因为数组在内存中是连续的,通过索引(Index)可以直接定位元素,时间复杂度为 O(1)。
劣势:插入和删除慢。因为在中间插入一个元素,后面的所有元素都要向后移动(System.arraycopy)。

LinkedList(链表实现):

结构:底层是双向链表。
优势:插入和删除快。只需要修改指针指向即可,不需要移动元素。
劣势:随机访问慢。查找第 N 个元素必须从头遍历,时间复杂度为 O(N)。

⚠️ 避坑指南:
在使用  List  获取元素时,要注意泛型的使用。虽然 Java 早期版本允许放入  Object ,但在现代开发中,务必指定泛型(如  List ),以避免运行时的类型转换异常(ClassCastException)。

  1. Set 接口:独特的集合

Set 的核心特点是无序且不可重复。它主要用于去重场景。

HashSet:底层基于 HashMap 实现,利用哈希算法保证元素的唯一性。存取速度极快,但不保证顺序。
TreeSet:基于红黑树实现,可以对元素进行自然排序或自定义排序。

  1. Map 接口:键值对的映射

Map不是 Collection 的子接口,它是一个独立的体系。它存储的是 Key-Value 对,Key 不允许重复。

HashMap:最常用的 Map 实现。基于数组+链表(JDK8 后引入红黑树)结构。允许 null 键和 null 值,非线程安全。
TreeMap:基于红黑树,会对 Key 进行排序。
LinkedHashMap:维护了插入顺序或访问顺序。

四、实战演练:容器综合应用

在实际开发中,我们经常需要结合 Scanner 输入和容器来处理数据。

例如,一个简单的学生成绩录入系统:

使用  Scanner  读取用户输入。
使用  ArrayList  存储学生对象。
使用  HashMap  统计每个分数段的人数。

在编写这类代码时,有几个细节值得注意:

循环控制:注意  while  循环的终止条件,避免死循环。
输入校验:用户可能会输入非法字符,需要使用  try-catch  或  hasNextInt()  进行防御性编程。
遍历方式:对于  List ,推荐使用增强 for 循环(For-Each)或迭代器;对于  Map ,推荐遍历  entrySet()  以同时获取键和值,效率最高。