Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java8 - How to add List<List<String>> to List<List<String>>

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?

like image 727
zxwang Avatar asked Nov 16 '25 23:11

zxwang


2 Answers

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.

like image 185
Nikolas Charalambidis Avatar answered Nov 18 '25 14:11

Nikolas Charalambidis


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.

like image 25
dani-vta Avatar answered Nov 18 '25 12:11

dani-vta



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!