 This tutorial contains examples of how to concatenate `List`s in Dart.

List is a data type that contains zero or more elements. In Dart, you can use the `List` class to store a value that can contain multiple elements. In case you need to combine two or more `List`s in Dart, it can be done in various ways. Dart has some built-in operators and methods for that purpose. Since a `List` is a subtype of `Iterable` in Dart, you can also use the methods of `Iterable` class. Below are the examples.

In this tutorial, have these two `List`s that will be combined into one.

``````  final List<int> a = [1, 2, 3];
final List<int> b = [4, 5];``````

## Using Concatenation Operator

Dart's `List` class has a concatenation operator, which uses `+` symbol. It returns the concatenation result of a `List` with another one. This operator doesn't modify any of the original `List`.

``  List<E> operator +(List<E> other);``

Example:

``````  final List<int> c = a + b;

print(a); // [1, 2, 3]
print(b); // [4, 5]
print(c); // [1, 2, 3, 4, 5]``````

Dart has spread (triple dot) operator which can be used for joining multiple `List`s. Like the `+` operator, the result is a new `List` and it doesn't modify any of the original `List`.

``````  final List<int> c = <int>[...a, ...b];

print(a); // [1, 2, 3]
print(b); // [4, 5]
print(c); // [1, 2, 3, 4, 5]``````

## Using `expand` Method

Dart's `Iterable` has `expand` operator, which is used to expand each element of the `Iterable` to one or more elements. Each element will run through the function passed as the `toElements` argument.

The idea is to create a `List` of `List`s, where the elements of the outer `List` are the `List`s to be combined. Then, flatten it by using the `expand` operator with an identity function passed as the `toElements` argument. That results in an `Iterable` which can be converted to a new `List` using `toList()` method.

``  Iterable<T> expand<T>(Iterable<T> toElements(E element))``

Example:

``````  final List<int> c = [a, b].expand((x) => x).toList();

print(a); // [1, 2, 3]
print(b); // [4, 5]
print(c); // [1, 2, 3, 4, 5]``````

## Using `reduce` Method

Another method of the `Iterable` class that you can use is `reduce`. It's used to reduce a collection to a single value by iteratively combining elements using the provided function. The provided function has two positional arguments. The first one is `value` which is the accumulated value. The second one is `element` which is the current element value. It has to return a value which will be passed as the `value` argument when processing the next element.

Like using the `expand` method, you need to create a `List` of `List`s. Then, call the `reduce` method by passing a function that concatenates the current `List` to the accumulated value.

``  E reduce(E combine(E value, E element))``

Example:

``````  final List<int> c = [a, b].reduce((value, element) => value + element);

print(a); // [1, 2, 3]
print(b); // [4, 5]
print(c); // [1, 2, 3, 4, 5]``````

## Using `fold` Method

The `fold` method of the `Iterable` class is similar to the `reduce` method. The difference is it requires you to pass an initial value as the first argument, while the function for combining the elements becomes the second argument. Therefore, you can use it to combine multiple `List`s as well.

``  T fold<T>(T initialValue, T combine(T previousValue, E element))``

Example:

``````  final List<int> c = [a, b].fold([], (previousValue, element) => previousValue + element);

print(a); // [1, 2, 3]
print(b); // [4, 5]
print(c); // [1, 2, 3, 4, 5]``````

## Using `followedBy` Method

The `followedBy` method returns the lazy concatenation of an `Iterable` and another one. It returns an `Iterable` whose elements are the same as the `Iterable` that invokes the method, followed by the elements of the `Iterable` passed as the argument in the same order. The result is an `Iterable` which can be converted to a `List` using the `toList` method.

``  Iterable<E> followedBy(Iterable<E> other)``

Example:

``````  final List<int> c = a.followedBy(b).toList();

print(a); // [1, 2, 3]
print(b); // [4, 5]
print(c); // [1, 2, 3, 4, 5]``````

## Using `addAll` Method

The `addAll` method is used to append all objects a passed `Iterable` to the end of the `List`. It modifies the `List` that calls the method.

``  void addAll(Iterable<E> iterable);``

Example:

``````  a.addAll(b);
print(a); // [1, 2, 3, 4, 5]
print(b); // [4, 5]``````

If you don't want to modify the elements of the original `List`, you can copy the `List` first and call `addAll` using the cascade notation.

``  final List<int> c = List.from(a)..addAll(b);``

## Summary

There are various ways to combine multiple lists in Dart. If you don't need to use custom logic, the `+` or spread operator can be a preferred solution because of their simplicity. Other than `addAll`, the operators and methods above will result in a new `List` and you can add or remove elements of the new `List` without affecting the original `List`s. However, you have to be careful if the elements are not primitive, since the elements may refer to the same objects. As a result, if you modify a non-primitive element of the new `List`, it also affects the same element of the original `List`.