I have two List<List<String>>
and would like to concatenate them.
Here is my code:
List<List<String>> a = Arrays.asList(Arrays.asList("a", "b", "c"));
List<List<String>> b = Arrays.asList(Arrays.asList("d", "e", "f"));
a.addAll(b);
However, it doesn't work and throws an exception.
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
The code below works:
List<List<String>> a = new ArrayList<>();
a.add(Arrays.asList("a", "b", "c"));
List<List<String>> b = new ArrayList<>();
b.add(Arrays.asList("d", "e", "f"));
a.addAll(b);
What's the difference here?
CodePudding user response:
Your attempt with a.addAll(b)
works as long as the outer list a
is mutable and you don't mind to modify it.
Mutable outer list:
List<List<String>> a = new ArrayList<>(List.of(
List.of("a", "b", "c"),
List.of("d", "e", "f")));
List<List<String>> b = new ArrayList<>(List.of(
List.of("h", "i", "j"),
List.of("k", "l", "m")));
a.addAll(b); // the 'a' will contain all the inner lists
a.forEach(System.out::println);
Immutable outer list
In case you want to preserve the former a
and b
lists and/or yield a new one, use java-stream:
List<List<String>> a = List.of(
List.of("a", "b", "c"),
List.of("d", "e", "f"));
List<List<String>> b = List.of(
List.of("h", "i", "j"),
List.of("k", "l", "m"));
List<List<String>> result = Stream.of(a, b)
.flatMap(Collection::stream)
.collect(Collectors.toList());
result.forEach(System.out::println);
Result
Both ways share the same output:
[a, b, c] [d, e, f] [h, i, j] [k, l, m]
Whether the inner lists are immutable or not doesn't matter for such combining.
CodePudding user response:
Your code doesn't work because the Arrays.asList()
returns
a fixed-size list backed by the specified array
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Arrays.html#asList(T...)
This means that when you try to add further elements, there is no space within the array representing the List
; thus throwing anUnsupportedOperationException
.
If you want to build List
with specific elements and also be able to extend its size, then you should employ the class' Conversion Constructor by providing to it the lists returned by the asList()
method.
List<List<String>> a = new ArrayList<>(Arrays.asList(new ArrayList<>(Arrays.asList("a", "b", "c"))));
List<List<String>> b = new ArrayList<>(Arrays.asList(new ArrayList<>(Arrays.asList("d", "e", "f"))));
a.addAll(b);
This way, both your outer and inner lists will behave as an actual List
without throwing an UnsupportedOperationException
when exceeding the original size.
CodePudding user response:
You could avoid using the addAll function and iterate through b and add to a like shown below:
for(innerList:b){
a.add(innerList);
}