在Dart列表中addAll()和followedBy()有什么区别?

dtcbnfnu  于 2023-06-03  发布在  其他
关注(0)|答案(2)|浏览(213)

我需要在Dart中连接两个列表,并且看到至少有两种不同的方法可以这样做。一个是list1.addAll(list2),另一个是list1.followedBy(list2)。我想知道有什么区别?文档将后者称为“惰性连接”。这是否意味着在第一种情况下,元素被复制,但在后者中仅被引用?或者还有别的什么?

mrfwxfqh

mrfwxfqh1#

延迟加载(在本例中为延迟串联)意味着某些资源在必要之前不会被评估。相比之下,急切加载(或急切串联)意味着资源被完全评估。
因此,惰性串联意味着已知要执行串联,但其最终评估被推迟到需要时。此外,急切级联意味着整个级联过程完全完成。

tpxzln5u

tpxzln5u2#

list1.addAll(list2)增长并突变list1以包含list2的元素。如果list2m 个元素,那么list1.addAll(list2)的内存消耗将增长O(m)。
更直观地说,如果你有:

list1                  list2
+---+---+---+---+      +---+---+
| o | o | o | o |      | o | o |
+-|-+-|-+-|-+-|-+      +-|-+-|-+
  |   |   |   |          |   |
  v   v   v   v          v   v
  A   B   C   D          E   F

那么list1.addAll(list2)将产生:

list1                       list2
+---+---+---+---+---+---+   +---+---+
| o | o | o | o | o | o |   | o | o |
+-|-+-|-+-|-+-|-+-|-+-|-+   +-|-+-|-+
  |   |   |   |   |   |       |   |
  v   v   v   v    \   \______|__ |
  A   B   C   D     \   ______/  \|
                     \ /          |
                      |           v
                      v           F
                      E

请注意,在此之后改变list2不会影响list1的内容。
list1.followedBy(list2)返回一个Iterable(* 不是 * 一个List)。当迭代Iterable时,将迭代list1,然后迭代list2list1.followedBy(list2)不会改变list1,因此不应分配新的Listlist1.followedBy(list2)的内存消耗将增长O(1),因为没有List s增长或创建。
在这种情况下,之后对list2进行突变 * 将 * 影响followedBy返回的Iterable

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]
}

相关问题