繁体   English   中英

为什么在数组列表数组上使用 Arrays.fill() 时会出现意外行为?

[英]Why do I get unexpected behaviour when I use Arrays.fill() on an array of array lists?

我知道混合集合和数组不是一个好主意,但我不明白为什么我会收到这个错误。

说,

ArrayList<Integer>[] x = new ArrayList[2];
Arrays.fill(x, new ArrayList<>());
x[0].add(1);

为什么x评估为ArrayList[2] { [1], [1] }即使我只是用那个值填充索引 0?

但是,这很好用,

ArrayList<Integer>[] x = new ArrayList[2];
for (int i = 0; i < n; i++) {
    x[i] = new ArrayList<Integer>();
} 
Arrays.fill(x, new ArrayList<>());
x[0].add(1);

x计算为ArrayList[2] { [0], [] }

在第一个Arrays.fill方法中究竟是什么导致了这种异常?

Arrays.fill(x, new ArrayList<>());

这是误导性的,不会做你想做的事。

具体来说,它这样做:

  1. 它创建一个新的 ArrayList 实例。 一例。 就一个。
  2. 然后它需要你的 ArrayLists 数组,当然,它是一个引用数组。 这是一个地址簿,里面有房子的地址,而不是房子的街区。
  3. 然后用同一个地址填充整个地址簿。 仍然只有一所房子。 您只创建了一个 ArrayList。

因此,您现在有一个数组,其中数组中的每个“槽”都指向完全相同的数组列表。 x[0]添加一个整数, x[0] x[1].size()现在也将返回 1。

修复?

嗯,你说的。 停止混合这两个概念的愚蠢行为。 更一般地说,您不能在此处使用fill

更新:但是有setAll

Arrays.setAll(x, idx -> new ArrayList<Integer>()); 做你想做的事:它为数组中的每个“插槽”调用数组之后的东西。

这是一个简单的规则:

如果您希望 Y 对象存在,那么请告诉我new Something()是如何至少运行 Y 次的。 如果你不能提出一个合理的案例,你猜怎么着。 你没有 Y 对象。

在您基于填充的代码中,我精确地计算了 1 个new ....调用,并且没有合理的解释来说明为什么以某种方式一次调用按您想要的方式运行多次(实际上,这就是解释:它不是't)。 因此:是的。 那个代码没有做你想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM