I have read that this is the most OK way of instantiating a modifiable list from an array
List<A> aList = new ArrayList<>(Arrays.asList(anArray));
Is there another way to instantiate a modifiable list from an array without double instantiation? I believe it is too redundant to convert the array to a list then convert that list again to an arraylist.
TIA!
CodePudding user response:
Arrays.asList(…)
creates a wrapper around the array. It does not copy anything. In fact, the list supports modifying the array via all methods not changing the list’s size.
E.g.
String[] array = { "foo", "bar", "baz" };
List<String> aList = Arrays.asList(array);
aList.set(2, "blah");
aList.sort(Comparator.naturalOrder());
aList.replaceAll(String::toUpperCase);
System.out.println(Arrays.toString(array));
[BAR, BLAH, FOO]
So if you don’t need a resizable list and are fine with modifying the original array, just using this list without copying it into a new ArrayList
might be your solution.
Depending on the Java version, ArrayList
’s constructor will just invoke toArray()
on the incoming list and use the result as its own internal array. With those versions, the construct new ArrayList<>(Arrays.asList(anArray))
does already the minimum work necessary to create an ArrayList
from an array’s content.
But in some versions, ArrayList
’s constructor will make a defensive copy of the array. If you really want to be sure that no additional array copying operation will be done in all versions, you may use
List<String> aList = new ArrayList<>(anArray.length);
Collections.addAll(aList, anArray);
But actual performance depends on complex surrounding conditions, e.g. the JIT or caches etc. may have unintuitive influence. It may turn out that even in versions where an addition defensive copy is made, new ArrayList<>(Arrays.asList(anArray))
will be faster than any alternative.
The bottom line is, use the simple idiomatic new ArrayList<>(Arrays.asList(anArray))
approach and only think about alternatives when you have an actual performance problem.
CodePudding user response:
You can do that using stream API :
List<A> aList = Stream.of(anArray).collect(Collectors.toCollection(ArrayList::new));