Java Collections:你错过的隐藏工具
大多数开发者每天使用 Java collections 的方式都大同小异。他们使用 ArrayLists 和 HashSets。但你可能错过了那些能让你的代码更快、更安全的工具。
这里有三个可以改进你代码的具体工具。
- Arrays.asList 并不是真正的 List
当你使用 Arrays.asList(array) 时,你得到的是一个固定大小的列表。它直接链接到你的原始数组。
- 如果你修改了数组,列表也会随之改变。
- 如果你尝试添加或删除元素,你的代码会因报错而崩溃。
要解决这个问题,请将其包装在一个新的 ArrayList 中:
List<String> list = new ArrayList<>(Arrays.asList(array));
这会创建一个可以修改的、真正的独立列表。
- 使用 EnumSet 提升性能
你是否在用 HashSet 存储 enums?这会产生不必要的开销。HashSet 使用哈希表和对象头。
改用 EnumSet。它在内部使用位向量(bit vector)。它速度极快,且几乎不占用内存。它非常适合像玩家能力或设置这类基于标志(flag)的系统。
- 它是类型安全的。
- 它比
HashSet快得多。 - 它能为你处理位运算。
- 为缓存使用 ConcurrentHashMap.computeIfAbsent
如果你在构建缓存,通常需要编写复杂的代码来防止多个线程计算同一个值。这被称为“双重检查锁定”(double-checked locking)。它难以阅读且容易出错。
相反,只需一行代码:
cache.computeIfAbsent(key, this::expensiveCalculation);
该方法是原子性的。它能确保即使许多线程同时请求同一个 key,计算也只会运行一次。它减少了 bug 并使你的意图更加清晰。
为什么这些工具很重要:
- 可预测的性能:避免隐藏的内存开销。
- 更少的 bug:停止在多线程代码中与竞态条件(race conditions)作斗争。
- 更清晰的代码:其他开发者能立即理解你的设计。
不要再与框架对抗。开始利用它来编写更精简、更安全的代码。