商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 如何利用 Arrays.fill() 快速为数组所有元素赋相同的初始值

如何利用 Arrays.fill() 快速为数组所有元素赋相同的初始值

  发布于2026-07-09 阅读(0)

扫一扫,手机访问

先放一个结论:如果你还在手写 for 循环去给数组赋值,那多半是时候换个思路了。Arrays.fill() 这个工具,底层直接由 JVM 做了 intrinsic 内联优化,基本类型数组走的是内存块拷贝,天然避免了手写循环常见的越界、漏判、下标错误。性能上,对基本类型也是实打实的更优。

如何利用 Arrays.fill() 快速为数组所有元素赋相同的初始值

为什么说 Arrays.fill() 比 for 循环更可靠?

关键在于它绕开了 Ja va 层面的边界检查。对于基本类型数组,比如 int[]double[],底层直接调用 ArraysSupport.fill,循环和边界判断的开销完全被消除。而自己手写 for 循环呢?稍不留神,i <= arr.length 还是 i < arr.length?写错了就是 ArrayIndexOutOfBoundsException

对于引用类型数组,Arrays.fill() 还有一个容易被忽略的好处:它可以帮你规避“浅拷贝陷阱”。举个例子,new String[10] 之后想把每一项设为 "N/A",用 Arrays.fill(arr, "N/A") 非常安全。但如果是手动赋值,逻辑上虽然没错,可一旦中间加了条件判断或者提前 break,漏填就几乎是必然的事。

重载版本那么多,常用的是哪几种?参数别搞混

实际开发中,绝大多数场景只需要记住三个版本:

  • Arrays.fill(int[] a, int val):最常用,整个 int[] 填一遍。
  • Arrays.fill(double[] a, int fromIndex, int toIndex, double val):只填指定区间。注意 toIndex 是**不包含**的,区间是 [fromIndex, toIndex),这个边界特性非常容易踩坑。
  • Arrays.fill(Object[] a, Object val):填对象数组。但你必须清楚,val 是个引用,结果就是数组里的所有元素指向同一个对象。

别用 Arrays.fill(byte[], byte) 去填 char[]——类型不匹配,编译就过不了。也别指望 Arrays.fill(boolean[], true) 能填 Boolean[],后者是引用类型,得用对应的对象版本。

引用类型数组填 null 或新对象时的陷阱

这部分是 bug 最密集的区域,值得多花点时间聊清楚:

  • null 是安全的。Arrays.fill(strArr, null) 的结果是每个元素都是独立的 null,互不影响。
  • 填同一个对象就很危险了。Arrays.fill(listArr, new ArrayList()) 之后,所有数组元素指向**同一个** ArrayList 实例。你调用任意一个 add(),所有元素都会受影响。
  • 如果需要每个元素都是独立的实例,那就必须用循环手动创建:for (int i = 0; i < listArr.length; i++) listArr[i] = new ArrayList();

一个很典型的错误现象:listArr[0].add("x"); 之后,System.out.println(listArr[1].size()); 输出居然是 1。出现这个问题的根本原因,就是误用了 Arrays.fill() 去填充可变对象。

性能差异在什么规模下才值得关注?

小数组上差距不大,但一旦数组规模上来,情况就不同了。在 JDK 17+ 的 HotSpot 上,Arrays.fill() 对基本类型的处理会自动向量化,实测下来平均快 2–3 倍。如果只是初始化一次,这点差距确实可以忽略;但如果是在高频循环里反复调用,比如每帧需要清空缓冲区,那切换成 Arrays.fill() 就很有必要了。

话说回来,Arrays.fill() 本身不支持并行——它不拆分任务,也不会用 ForkJoinPool。如果真要并行填充超大数组(比如百万级的 float[]),那就得自己动手,用 ForkJoinPool.commonPool().submit(...) 分段处理,或者改用 Arrays.setAll() 配合 lambda。不过后者已经不属于“相同初始值”的应用场景了。

最后提醒一个容易被忽略的细节:Arrays.fill() 不会触发 GC,也不会校验 val 是否为 null。对对象数组来说,传错引用也不会立刻报错,问题会一直延后到实际使用时才暴露——这才是最让人头疼的地方。

本文转载于:https://www.php.cn/faq/2405119.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注