【问题标题】:Why do I get unexpected behaviour when I use Arrays.fill() on an array of array lists?为什么在数组列表数组上使用 Arrays.fill() 时会出现意外行为?
【发布时间】:2021-09-28 04:58:19
【问题描述】:

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

说,

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 方法中究竟是什么导致了这种异常?

【问题讨论】:

  • 我刚刚尝试了这两段代码,在这两种情况下x 都会评估您的第一个示例,这是正确的行为。有什么问题?

标签: java arrays arraylist collections


【解决方案1】:

Arrays.fill(x, new ArrayList&lt;&gt;());

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

具体来说,它是这样做的:

  1. 它创建一个新的 ArrayList 实例。一个例子。只有一个。
  2. 然后它会获取您的 ArrayList 数组,这当然是一个引用数组。这是一个地址簿,上面有房子的地址,而不是一栋房子。
  3. 然后它用同一个地址填充整个地址簿。仍然只有一所房子。您只创建了一个 ArrayList。

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

解决办法?

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

更新:但是有setAll

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

这是一个简单的规则:

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

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

【讨论】:

猜你喜欢
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
相关资源
最近更新 更多