I'm trying to initialize an ArrayList from an Array, but just the subarray, given the original array and subarray start and end index.
I can only think of doing something like this to create a new list from the subarray:
Arrays.asList(Arrays.copyOfRange(arr, i, j));
or just manually add elements to a list
List<Integer> result = new ArrayList<>(k);
for (int i = left; i < left + k; i++) {
result.add(arr[i]);
}
Which obviously isn't very pretty. Is there better way to do it by just passing in array and indexes?
"Better" depends on your requirements, and use case. Since you suggested using Arrays.asList(...)
, which returns a fixed size list, I will assume here that a fixed size list is sufficient for your needs.
Probably the fastest way would be to use
Arrays.asList(arr).subList(i, j);
This will be quick, because no elements are copied anywhere, and no iteration is performed. Arrays.asList(arr)
essentially creates a list which is a wrapper for the original array, and subList(...)
creates a list which is a view of the existing list.
The trade-off (there is always a trade-off) is that this retains a reference to the original array. So if you were generating a large number of large arrays, and wanted to keep a small slice of each one, this would be a poor choice from a memory-consumption perspective. (Conversely, if you had one large array, and wanted a large number of different slices of it, potentially overlapping, this would be a very memory-efficient approach as well as being fast.)
If memory considerations mean that you need to release any reference to the original array, then you are forced to copy elements to a new structure somehow. Probably the most efficient way to do this is to use the approach you suggested: Arrays.copyOfRange(...)
basically delegates to System.arrayCopy(...)
, which is essentially implemented natively on most systems (bulk copy of a contiguous chunk of memory), and then as before Arrays.asList(...)
just creates a list wrapper for that new array. So in the scenario that you want to release the reference to the original array, your suggested
Arrays.asList(Arrays.copyOfRange(arr, i, j));
is probably the "best" approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With