FastUtil 高性能集合最佳实践:让你的 Java 程序真正“快”起来

FastUtil 是由意大利计算机科学家 Sebastiano Vigna 维护的开源库,它为 Java 原始类型(primitive types)提供了类型特化的集合实现 ,性能通常比 JDK 集合快 2~5 倍 ,内存占用降低 40%~70%。在高性能后端、游戏服务器、大数据处理、量化交易等场景中,几乎是标配。

本文总结 2025 年最新的 FastUtil(当前版本 8.5.15+)常用 API 及生产级最佳实践,帮你避开所有常见坑。

1. 为什么选择 FastUtil?

场景 JDK HashMap<Integer, Long> FastUtil Int2LongOpenHashMap
内存占用(1000万条) ~1.1 GB ~320 MB
put/get 速度 基准 2.8~4.5×
GC 压力 高(大量 Integer/Long 包装对象) 极低(零装箱)

2. 核心集合类型速查表(记住这 8 个就够日常 95% 场景)

原始类型 List Set Map(key→value)
int IntArrayList IntOpenHashSet Int2IntOpenHashMap、Int2ObjectOpenHashMap
long LongArrayList LongOpenHashSet Long2LongOpenHashMap、Long2ObjectOpenHashMap
double DoubleArrayList DoubleOpenHashSet Double2DoubleOpenHashMap
float FloatArrayList FloatOpenHashSet ------
byte ByteArrayList ByteOpenHashSet Byte2IntOpenHashMap
char CharArrayList CharOpenHashSet ------
short ShortArrayList ------ ------
boolean ------ BooleanOpenHashSet ------

推荐永远使用 OpenHash 系列(默认实现),它比旧的 RBTree/Champ 更快且内存更省。

3. 最佳实践代码示例(直接可复制)

3.1 基本替换(最常见)

java 复制代码
// 差:大量装箱 + 高内存
Map<Integer, Long> map = new HashMap<>();

// 好:零装箱 + 极致性能
Int2LongOpenHashMap map = new Int2LongOpenHashMap();

// 常用构造方式
Int2LongOpenHashMap map = new Int2LongOpenHashMap(1_000_000);           // 预估容量
Int2LongOpenHashMap map = new Int2LongOpenHashMap(1_000_000, 0.8f);     // 指定负载因子

3.2 推荐初始化方式(避免频繁扩容)

java 复制代码
// 最佳:预估容量 + 高负载因子(FastUtil 默认 0.8~0.9,比 JDK 0.75 高)
int expectedSize = 5_000_000;
Int2ObjectOpenHashMap<User> userMap = new Int2ObjectOpenHashMap<>(expectedSize, 0.9f);

// 如果你能接受极少数 rehash,负载因子甚至可以调到 0.95f
Int2IntOpenHashMap counter = new Int2IntOpenHashMap(100_000, 0.95f);

3.3 高频操作性能对比 & 推荐写法

java 复制代码
Int2LongOpenHashMap map = new Int2LongOpenHashMap();

// 1. get 默认值(避免 containsKey + get 两次查找)
long value = map.getOrDefault(userId, 0L);           // 推荐
long value = map.containsKey(id) ? map.get(id) : 0L; // 慢 2 倍!

// 2. 计数器模式(比 compute 快 3~5 倍)
map.addTo(userId, 1L);                               // 原子 + 极快
// 等价于 map.put(userId, map.getOrDefault(userId, 0L) + 1);

// 3. 自增 1 的最快写法
map.addTo(key, 1L);

// 4. 批量插入(FastUtil 独有 API,比 putAll 快 30%)
int[] keys = ...;
long[] values = ...;
map.putAll(IntArrays.forceCopy(keys), LongArrays.forceCopy(values), keys.length);

3.4 List 使用技巧

java 复制代码
// 动态数组(比 ArrayList<Integer> 快 3~5 倍)
IntArrayList list = new IntArrayList();
list.add(1);
list.add(2);

// 快速转成原始数组(零拷贝!)
int[] array = list.elements();           // 注意:不要再往 list 里 add!
int[] safeArray = list.toIntArray();     // 推荐:防御性拷贝

// 从已有数组创建(零拷贝)
int[] raw = new int[]{1,2,3,4};
IntArrayList list = IntArrayList.wrap(raw);  // 直接包装,不复制

3.5 Set 使用技巧

java 复制代码
IntOpenHashSet set = new IntOpenHashSet(1_000_000, 0.9f);

set.add(123);
if (set.add(123)) { /* 第一次插入 */ }

// 快速转原始数组
int[] array = set.toArray(new int[set.size()]);

3.6 与 Java Stream 配合(推荐方式)

java 复制代码
Int2LongOpenHashMap map = ...;

// FastUtil 自带原始流,比装箱流快 5~10 倍
long sum = map.int2LongEntrySet()
              .fastForEach(entry -> total += entry.getLongValue());

// 或者并行原始流
map.int2LongEntrySet().parallelStream()
   .forEach(entry -> updateSomeGlobalCounter(entry));

3.7 序列化注意事项

java 复制代码
// FastUtil 默认实现了 Serializable,但建议显式指定版本
private static final long serialVersionUID = 1L;

// 大 Map 序列化建议使用 FastUtil 自带的二进制格式(比 JDK 快 5~10 倍)
ByteBufferOutput out = ...;
Int2LongBinaryOpenHashMap.write(out, map);   // 极快!

4. Maven/Gradle 依赖(2025 最新)

xml 复制代码
<!-- Maven -->
<dependency>
    <groupId>it.unimi.dsi</groupId>
    <artifactId>fastutil</artifactId>
    <version>8.5.15</version>
</dependency>
kotlin 复制代码
// Gradle Kotlin DSL
implementation("it.unimi.dsi:fastutil:8.5.15")

5. 生产环境避坑清单(血泪经验)

坑点 正确做法
使用 new HashMap<Integer,...> 改用 new Int2XxxOpenHashMap()
map.get(key) 返回包装类 使用原始方法 map.getOrDefault(intKey, 0L)
List 使用 ArrayList<Integer> 改用 IntArrayList
for (Integer i : list) for (int i : list)IntIterator
序列化超大 Map 超时 改用 FastUtil 二进制序列化 API
并发修改导致异常 使用 Int2LongOpenHashMap + 分段锁或外部锁

6. 结论:一条替换原则

只要键或值是原始类型,且预计 size > 10万,就必须使用 FastUtil。

记住一句话:

"在 Java 里,装箱是性能杀手,FastUtil 是解药。"

把这篇文章加入你的团队 Wiki,下次代码审查看到 HashMap<Integer, ... 就直接贴链接。

项目推荐

快起来吧,你的 CPU 会感谢你!

相关推荐
Amos_Web2 小时前
Rust实战(四):数据持久化、告警配置与Web API —— 构建监控系统的功能闭环
前端·后端·rust
.豆鲨包2 小时前
【Android】 View事件分发机制源码分析
android·java
北京地铁1号线2 小时前
数据结构:堆
java·数据结构·算法
百***86462 小时前
Spring Boot应用关闭分析
java·spring boot·后端
tanxiaomi2 小时前
Spring、Spring MVC 和 Spring Boot ,mybatis 相关面试题
java·开发语言·mybatis
00后程序员2 小时前
WebApp 上架 iOS 的可行性分析,审查机制、技术载体与工程落地方案的全流程说明
后端
Java水解2 小时前
从零开始打造高性能数据结构——手把手教你实现环形缓冲
后端
弥巷2 小时前
【Android】常见滑动冲突场景及解决方案
android·java
浮尘笔记2 小时前
Go并发编程核心:Mutex和RWMutex的用法
开发语言·后端·golang