简体   繁体   中英

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?

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 :

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.

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 an UnsupportedOperationException .

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.

You could avoid using the addAll function and iterate through b and add to a like shown below:

for(innerList:b){
   a.add(innerList);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM