简体   繁体   中英

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

I know it is not a good idea to mix up collections and arrays, but I am not getting why exactly I am getting this error.

Say,

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

Why does x evaluate to ArrayList[2] { [1], [1] } now even though I am just filling index 0 with that value?

This works fine however,

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 evaluates to ArrayList[2] { [0], [] }

What exactly causes this anomaly in the first Arrays.fill approach?

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

This is misleading and doesn't do what you want.

Specifically, it does this:

  1. It creates a new ArrayList instance. One instance. Just the one.
  2. It then takes your array of ArrayLists, which is, of course, an array of references. It's an address book with addresses to houses, not a block of houses.
  3. It then fills the entire addressbook with the same one address . There is still just one house. You've only made a single ArrayList.

Thus, you now have an array, where each 'slot' in the array is pointing at the exact same arraylist. Add an integer to x[0] and the x[1].size() will now return 1 as well.

The fix?

Well, you said it. Stop with this silly crud of mixing the two concepts. More generally, you cannot use fill here .

UPDATE: But there is setAll :

Arrays.setAll(x, idx -> new ArrayList<Integer>()); does what you want: It invokes the thing after the array for every 'slot' in your array.

Here's a simple rule:

If you want Y objects to exist, then show me how new Something() is being run at least Y times. If you can't make a plausible case, guess what. You don't have Y objects.

In your fill based code, I count precisely 1 new .... invocation, and there is no plausible explanation available as to why somehow that one invocation is run as many times as you want (and indeed, that is the explanation: It isn't). Thus: Yup. That code doesn't do what you wanted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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