发布于2026-07-09 阅读(0)
扫一扫,手机访问
Ja va里需要快速生成大量重复元素时,很多人的第一反应可能是用for循环往ArrayList里加。但有没有想过,如果只是为了占个位置、设置个默认值,或者构建测试数据,完全不用真的在内存里复制那么多份对象?Collections.nCopies() 就是为此而生的一个轻量工具。
先理解它的内存节省原理。nCopies() 返回的不是ArrayList或LinkedList,而是一个叫做 CopiesList 的私有内部类。它内部只存了三个东西:一个是对被复制元素的引用(element),一个是你指定的数量(n),还有一个懒加载的hashCode。也就是说,无论你让nCopies生成100个元素还是一百万个元素,它在内存里占用的空间几乎不变——因为根本没有真正创建那n个副本,所有逻辑位置都指向同一个实例。打个比方,它就像一个“数字占位符”,只告诉你这里该有这么多相同的元素,但实际只有一个原件。
当然,代价也很明显:它返回的是一个只读视图。不支持add、remove、set这类修改操作,一旦尝试调用这些方法,就会毫不客气地抛出 UnsupportedOperationException。
List defaultRoles = Collections.nCopies(1000, "USER");
List zeros = Collections.nCopies(1_000_000, 0);
这一个List对象占用的内存大约是24个字节左右,而不是你以为的四兆(4MB)。
Collections.frequency() 计算出现次数,或者用于 Collections.binarySearch()(前提是元素本身可比较)。new ArrayList<>() 或者自定义的可变对象,那么所有“逻辑位置”引用的都是同一个实例。改动其中一个位置的内容,等于改了全部。这往往不是你想要的效果。new ArrayList<>(Collections.nCopies(...)) 能创建一个真正的可变副本,但这样做的意义就大打折扣——你不仅失去了内存优势,还容易混淆,以为原始的nCopies视图也可以修改。Collections.nCopies(3, null) 返回的是 List。如果希望得到一个 List,需要显式指定泛型类型,或者谨慎处理null。回过头来看,nCopies() 适用的场景其实很清晰:元素本身是不可变值(像String、Integer、枚举),不需要结构修改,而且随机访问性能有保障(它的 get(i) 是 O(1))。如果满足这些条件,它就是最优解。
反之,情况就不一样了:
ArrayList 加构造器:new ArrayList<>(Collections.nCopies(1000, "A"))。new int[1000] 更简单直接,不用绕弯子。选择工具时,清楚自己的真实需求比什么都重要。nCopies() 的定位就是“轻量级占位”,它不万能,但用对地方,能省下不少内存和代码量。
上一篇:如何在 Java 中使用 Iterator.next() 配合 NoSuchElementException 编写健壮的自定义迭代器
下一篇:数据校验流 CheckedInputStream:解析如何利用 Checksum 在读取流的过程中同步计算 CRC32
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8