Pitfalls of Using Arrays.asList and ArrayList.subList in Java
This article explains common traps when using Java's Arrays.asList and ArrayList.subList methods, including why add operations throw UnsupportedOperationException, how subList creates a view that shares modifications with the original list, and the circumstances that lead to ConcurrentModificationException.
When converting an array to a list with Arrays.asList , the returned list is a fixed‑size view backed by an internal ArrayList implementation that does not support structural modifications such as add or remove . Attempting to call add on the list results in a java.lang.UnsupportedOperationException , as demonstrated by the example:
List
statusList = Arrays.asList(1, 2);
System.out.println(statusList);
System.out.println(statusList.contains(1));
System.out.println(statusList.contains(3));
// statusList.add(3); // throws UnsupportedOperationExceptionThe underlying implementation is an inner class of Arrays , not the usual java.util.ArrayList , and it only overrides read‑only methods like contains while leaving mutating methods unsupported.
According to the Alibaba Java Development Manual, collections created with Arrays.asList should be used only for read‑only purposes such as quick initialization or range checks.
Using ArrayList.subList
The subList method returns a view of the original list between fromIndex (inclusive) and toIndex (exclusive). Because it is a view, any non‑structural change (e.g., set ) to either the original list or the sub‑list is reflected in the other:
List
bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");
List
sub = bookList.subList(3, 5);
bookList.set(3, "路遥-人生"); // sub now sees the change
sub.set(1, "路遥-平凡的世界"); // bookList sees the changeStructural modifications (adding or removing elements) to the original list while iterating the sub‑list cause a ConcurrentModificationException . Likewise, modifying the sub‑list’s structure also affects the original list:
// Adding to original list after creating subList
bookList.add("新元素"); // later iteration of sub throws ConcurrentModificationException
// Adding to subList
sub.add("额外元素"); // original list now contains the new elementThe source code of subList simply creates a new SubList instance that shares the backing ArrayList , which explains why changes are mirrored.
In summary, Arrays.asList should be used only for immutable list scenarios, and ArrayList.subList should be handled with care: non‑structural changes affect both views, while structural changes can trigger UnsupportedOperationException or ConcurrentModificationException .
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.