news 2026/4/23 12:00:54

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FastUtil 高性能集合最佳实践:让你的 Java 程序真正“快”起来

👉这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:

  • 《项目实战(视频)》:从书中学,往事中“练”

  • 《互联网高频面试题》:面朝简历学习,春暖花开

  • 《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题

  • 《精进 Java 学习指南》:系统学习,互联网主流技术栈

  • 《必读 Java 源码专栏》:知其然,知其所以然

👉这是一个或许对你有用的开源项目

国产Star破10w的开源项目,前端包括管理后台、微信小程序,后端支持单体、微服务架构

RBAC权限、数据权限、SaaS多租户、商城、支付、工作流、大屏报表、ERP、CRMAI大模型、IoT物联网等功能:

  • 多模块:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • 微服务:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK17/21+SpringBoot3、JDK8/11+Spring Boot2双版本

  • 1. 为什么选择 FastUtil?

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

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

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

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

  • 6. 结论:一条替换原则



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 包装对象)

极低(零装箱)


场景

JDK HashMap<String, Object>

FastUtil Object2ObjectOpenHashMap<String, Object>

内存占用(1000万条)

~1.2 GB

~720 MB

put/get 速度

基准

1.5~3×(优化哈希 + 引用相等)

GC 压力

中等(String 不可变,但 Object 可能有引用)

低(高效迭代 + 零额外包装)

关键:String 不是原始类型,所以无String2StringOpenHashMap专用类,但Object2ObjectOpenHashMap<String, String>等通用类已足够高效。启用引用相等(reference equality)可进一步加速(用==而非equals())。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

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

原始类型

List

Set

Map(key→value)

Object

(e.g., String)

ObjectArrayList

ObjectOpenHashSet

Object2ObjectOpenHashMap<String, Object>、Object2ObjectOpenHashMap<String, String>

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 更快且内存更省。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

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

3.1 基本替换(最常见)
// 差:大量装箱 + 高内存 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 推荐初始化方式(避免频繁扩容)
// 最佳:预估容量 + 高负载因子(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 高频操作性能对比 & 推荐写法
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 使用技巧
// 动态数组(比 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 使用技巧
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 配合(推荐方式)
Int2LongOpenHashMap map = ...; // FastUtil 自带原始流,比装箱流快 5~10 倍 long sum = map.int2LongEntrySet() .fastForEach(entry -> total += entry.getLongValue()); // 或者并行原始流 map.int2LongEntrySet().parallelStream() .forEach(entry -> updateSomeGlobalCounter(entry));
3.7 序列化注意事项
// FastUtil 默认实现了 Serializable,但建议显式指定版本 private static final long serialVersionUID = 1L; // 大 Map 序列化建议使用 FastUtil 自带的二进制格式(比 JDK 快 5~10 倍) ByteBufferOutput out = ...; Int2LongBinaryOpenHashMap.write(out, map); // 极快!
3.8 String-Object / String-String 替换(最常见场景)
// 差:JDK 通用,性能一般 Map<String, Object> map = new HashMap<>(); Map<String, String> config = new HashMap<>(); // 好:FastUtil Object 优化,内存/速度提升明显 Object2ObjectOpenHashMap<String, Object> objMap = new Object2ObjectOpenHashMap<>(); Object2ObjectOpenHashMap<String, String> strMap = new Object2ObjectOpenHashMap<>(); // 常用构造:预估容量 + 负载因子(避免 rehash) int expectedSize = 500_000; // 如配置项或缓存 Object2ObjectOpenHashMap<String, Object> objMap = new Object2ObjectOpenHashMap<>(expectedSize, 0.9f); Object2ObjectOpenHashMap<String, String> strMap = new Object2ObjectOpenHashMap<>(expectedSize, 0.9f); // 启用引用相等(推荐:String 场景下加速 20%~30%,但需确保无 null) objMap.referenceEquality(); // 或 strMap.referenceEquality();
3.9 高频操作性能对比 & 推荐写法(Object 版)
Object2ObjectOpenHashMap<String, Object> map = new Object2ObjectOpenHashMap<>(); // 1. get 默认值(单次查找,避免 containsKey + get) Object value = map.getOrDefault("userKey", null); // 推荐,零额外开销 // 2. 合并操作(Object 版 computeIfAbsent,比 JDK 快 2x) map.computeIfAbsent("key", k -> new Object()); // 如懒加载 JSON 对象 // 3. 计数器模式(String key + int value,用混合类型更优) Object2IntOpenHashMap<String> counter = new Object2IntOpenHashMap<>(); counter.addTo("item", 1); // 原子自增,比纯 Object 快 3~5x // 4. 批量插入(FastUtil 独有,适用于 CSV/JSON 加载) String[] keys = {"k1", "k2"}; Object[] values = {new Object(), "val2"}; map.putAll(keys, values, keys.length); // 比 putAll 快 25%~40%
3.10 List/Set 使用技巧(String 版)
// 动态 String 列表(比 ArrayList<String> 快 2~4x,内存省 30%) ObjectArrayList<String> list = new ObjectArrayList<>(); list.add("item1"); list.add("item2"); // 快速转数组(零拷贝) String[] array = list.toStringArray(); // 防御性拷贝,推荐 // 从数组创建(零拷贝包装) String[] raw = {"a", "b", "c"}; ObjectArrayList<String> list = ObjectArrayList.wrap(raw); // Set 去重 String(高效哈希) ObjectOpenHashSet<String> set = new ObjectOpenHashSet<>(1_000_000, 0.9f); set.add("unique"); if (set.add("duplicate")) { /* 插入成功 */ } String[] uniqueArray = set.toStringArray();
3.11 与 Java Stream 配合(Object 流优化)
Object2ObjectOpenHashMap<String, String> map = ...; // FastUtil 原始迭代器流(比 JDK stream 快 3~7x,无装箱) long count = map.object2ObjectEntrySet() .fastForEach(entry -> total += entry.getKey().length()); // e.g., 统计键长度 // 并行处理(大 String 集合) map.object2ObjectEntrySet().parallelStream() .forEach(entry -> process(entry.getStringKey(), entry.getStringValue()));
3.12 序列化注意事项(Object 版)
// Object Map 序列化:用 FastUtil 二进制(比 JDK 快 4~8x) ByteBufferOutput out = ...; Object2ObjectOpenHashMap.writeObject2Object(out, map); // 专为 Object2Object // 反序列化 Object2ObjectOpenHashMap<String, Object> loaded = Object2ObjectOpenHashMap.readObject2Object(in);

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

<!-- Maven --> <dependency> <groupId>it.unimi.dsi</groupId> <artifactId>fastutil</artifactId> <version>8.5.15</version> </dependency> // 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

改用IntArrayList

for (Integer i : list)

用for (int i : list)或IntIterator

序列化超大 Map 超时

改用 FastUtil 二进制序列化 API

并发修改导致异常

使用Int2LongOpenHashMap+ 分段锁或外部锁

使用new HashMap<String, Object>

改用new Object2ObjectOpenHashMap<String, Object>()+referenceEquality()

String key + 原始 value 仍用 Object

优先Object2IntOpenHashMap(混合优化)

迭代 Object 集合用 for-each(隐含 equals() 调用)

用fastIterator()或referenceEquality()加速

大 String Set 内存爆炸

用ObjectOpenHashSet+ 预估容量

null key/value 处理

FastUtil 默认不支持 null key;用defaultReturnValue()设置默认值

与 Lombok/Spring Boot 集成冲突

显式导入it.unimi.dsi.fastutil.objects.*

6. 结论:一条替换原则

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

  • 对于 String/Object:预计size > 5万,或频繁 get/put 时,用Object2ObjectOpenHashMap替换 HashMap,提升 20%+ 性能。

记住一句话:

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

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

项目推荐

  • https://github.com/vigna/fastutil

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


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。 谢谢支持哟 (*^__^*)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 12:00:14

信息管理毕业设计最全选题指导

0 选题推荐 - 云计算篇 毕业设计是大家学习生涯的最重要的里程碑&#xff0c;它不仅是对四年所学知识的综合运用&#xff0c;更是展示个人技术能力和创新思维的重要过程。选择一个合适的毕业设计题目至关重要&#xff0c;它应该既能体现你的专业能力&#xff0c;又能满足实际应…

作者头像 李华
网站建设 2026/4/23 11:58:19

Mac Mouse Fix终极指南:三步将普通鼠标打造成macOS效率神器

Mac Mouse Fix终极指南&#xff1a;三步将普通鼠标打造成macOS效率神器 【免费下载链接】mac-mouse-fix Mac Mouse Fix - Make Your $10 Mouse Better Than an Apple Trackpad! 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 你是否曾为macOS上第三方…

作者头像 李华
网站建设 2026/4/23 11:56:18

零基础到量化交易专家:QuantConnect教程库的完整学习路径指南

零基础到量化交易专家&#xff1a;QuantConnect教程库的完整学习路径指南 【免费下载链接】Tutorials Jupyter notebook tutorials from QuantConnect website for Python, Finance and LEAN. 项目地址: https://gitcode.com/gh_mirrors/tutorials2/Tutorials 想要从金融…

作者头像 李华
网站建设 2026/4/23 11:54:44

高效网络资源管理:Kemono Downloader GUI深度技术解析

高效网络资源管理&#xff1a;Kemono Downloader GUI深度技术解析 【免费下载链接】Kemono-Downloader-GUI Kemono Downloader with WinUI3 | Kemono下载器&#xff0c;使用WinUI3构建 项目地址: https://gitcode.com/gh_mirrors/ke/Kemono-Downloader-GUI Kemono Downl…

作者头像 李华