I need to concatenate two lists in Dart and saw that there are at least two different methods to do so. One is list1.addAll(list2)
and the other is list1.followedBy(list2)
.
I wonder what's the difference? The documentation refers to the latter as "lazy concatenation". Does it mean that under the hood the elements are copied in the first case, but only referenced in the latter? Or is there something more?
CodePudding user response:
Lazy loading (in this case lazy concatenation) means that some resources are not evaluated before they are necessary. By contrast, eager loading (or eager concatenation) means that the resource is fully evaluated.
So, lazy concatenation means that the concatenation is known to be executed, but its final evaluation is postponed until it is needed. Also, eager concatenation means that the whole concatenation process is fully done.
CodePudding user response:
list1.addAll(list2)
grows and mutates list1
to include the elements of list2
. If list2
has m elements, then memory consumption from list1.addAll(list2)
will by grow O(m).
More visually, if you have:
list1 list2
--- --- --- --- --- ---
| o | o | o | o | | o | o |
-|- -|- -|- -|- -|- -|-
| | | | | |
v v v v v v
A B C D E F
then list1.addAll(list2)
will produce:
list1 list2
--- --- --- --- --- --- --- ---
| o | o | o | o | o | o | | o | o |
-|- -|- -|- -|- -|- -|- -|- -|-
| | | | | | | |
v v v v \ \______|__ |
A B C D \ ______/ \|
\ / |
| v
v F
E
Note that mutating list2
afterward will not affect the contents of list1
.
list1.followedBy(list2)
returns an Iterable
(not a List
). When you iterate over the that Iterable
, you will iterate over list1
and then iterate over list2
. list1.followedBy(list2)
does not not mutate list1
and should not allocate a new List
. Memory consumption from list1.addAll(list2)
will grow by O(1) since no List
s are grown nor created.
In this case, mutating list2
afterward will affect* the Iterable
returned by followedBy
:
void main() {
var list1 = [1, 2, 3];
var list2 = [4, 5, 6];
var list1Copy = [...list1];
list1Copy.addAll(list2);
print(list1Copy); // Prints: [1, 2, 3, 4, 5, 6]
var concatenated = list1.followedBy(list2);
print(concatenated.toList()); // Prints: [1, 2, 3, 4, 5, 6]
list2.add(7);
print(list1Copy); // Prints: [1, 2, 3, 4, 5, 6]
print(concatenated.toList()); // Prints: [1, 2, 3, 4, 5, 6, 7]
}```