collections.fill() 不扩容,只覆盖现有元素;空 arraylist 填不满,需先初始化长度;仅适用于固定大小、批量赋相同值的场景,且要求列表可修改、类型匹配、注意引用共享问题。

为什么 Collections.fill() 填不满你新建的 ArrayList?
它根本不会扩容,只按现有索引位置赋值。如果你用 new ArrayList() 创建空集合,调用 Collections.fill(list, "a") 后 list 仍是空的——因为没元素可填。
必须先确保 list 已有确定大小(比如用 Arrays.asList() 初始化,或提前 add() 足够多占位元素)。
- 正确做法:先创建含 n 个
null或默认值的 list,再 fill - 错误写法:
new ArrayList<string>().fill(...)</string>——ArrayList没fill()方法,那是Collections的静态方法 - 常见报错:
IndexOutOfBoundsException,说明 list 长度为 0 或小于你要填的范围
Collections.fill() 的实际可用场景有哪些?
它适合「已有固定长度、只需批量覆盖值」的场合,比如初始化一个已知大小的缓存槽、重置某段日志缓冲区、填充测试用的等长数据桩。
- 配合
Arrays.asList(new String[10])使用最稳妥:数组长度固定,转成 list 后可直接 fill - 不能用于
LinkedList性能敏感场景:它会遍历索引,LinkedList的get(i)是 O(n),整体变 O(n²) - 对
ArrayList安全,底层是数组,随机访问快
示例:
List<string> list = new ArrayList(Collections.nCopies(5, null)); Collections.fill(list, "default"); // → ["default", "default", ..., 5 个]</string>
填不满、填错位置?检查这三个参数细节
Collections.fill() 只接受两个参数:List 和 obj,不支持起始/结束索引。想填部分区域?它做不到——得手写循环或用 subList().fill()(但 subList 返回的是视图,fill 会影响原 list)。
- 传入的 list 必须是可修改的(
Arrays.asList()返回的 list 支持 set,但不支持 add/remove;Collections.unmodifiableList()会抛UnsupportedOperationException) - 元素类型要匹配:往
List<integer></integer>里 fill"abc"会编译失败(泛型擦除后运行时可能出ClassCastException) - 如果 list 包含 null,fill 后 null 被替换;如果原 list 有真实值,那些值会被无条件覆盖
替代方案:什么时候不该硬用 Collections.fill()?
当你要生成新 list、或长度不确定、或需要函数式构造时,Collections.fill() 就不是最优解。
- 初始化固定长度新 list:用
Stream.generate(() -> "x").limit(10).collect(Collectors.toList()) - 填充不同值(如递增序号):必须循环或 stream map,
fill()只能塞同一个引用 - 并发环境:
Collections.fill()不保证线程安全,list 本身得是线程安全实现(如CopyOnWriteArrayList),且 fill 过程中不能被其他线程修改
真正容易被忽略的是:它操作的是引用。如果填的是可变对象(比如 new Date()),所有位置指向同一个实例——改一个,全部跟着变。










