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:
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.