在Dart中克隆列表,地图或集

Pat*_*lin 33 collections clone dart

从Java背景的:什么是推荐的方式来"克隆"一个飞镖List,MapSet

Pat*_*lin 48

clone()在Java中的使用是棘手和可疑的1,2.实际上,clone()是拷贝构造函数和针对的飞镖List,MapSet类型都有一个名为constructor名为.from()执行一个浅拷贝 ; 例如,给出这些声明

  Map<String, int> numMoons, moreMoons;
  numMoons = const <String,int>{ 'Mars' : 2, 'Jupiter' : 27 };
  List<String> planets, morePlanets;
Run Code Online (Sandbox Code Playgroud)

你可以.from()像这样使用:

  moreMoons = new Map<String,int>.from(numMoons)
    ..addAll({'Saturn' : 53 });
  planets = new List<String>.from(numMoons.keys);
  morePlanets = new List<String>.from(planets)
    ..add('Pluto');
Run Code Online (Sandbox Code Playgroud)

请注意,List.from()更通常接受迭代器而不仅仅是a List.

为了完整起见,我应该提到dart:html Node该类定义了一个clone()方法.


1 J. Bloch," Effective Java "第2版,第11项
.2 B. Venners," Josh Bloch on Design:Copy Constructor vs. Cloning ",2002.从这里引用3.从文章引用:

如果您已经阅读了我的书中有关克隆的项目,特别是如果您在这些内容之间进行了阅读,您将会知道我认为克隆已经深受打击.--- J.Bloch

3 Dart问题#6459,克隆实例(对象).

  • Josh Bloch实际上参与了Dart集合API的一些早期设计.[旧访谈](https://www.youtube.com/watch?v=wmsVHdllIPM). (5认同)
  • 正确的。`.from()` 是一个浅拷贝构造函数。需要澄清的是,我从未说过“.from()”执行了克隆操作。我写的是“clone()”是一种复制构造函数。 (3认同)
  • .from()和.addAll()并不是真正的克隆。他们在新的地图/列表/集合中添加参考。例如:Map map1 = {'one':{'name':1},'two':{'name':2},'three':[{'a':{'A':1,'B ':2},'b':{'A':3,'B':4}}]}}; 地图map2 = new Map.from(map1); map2 ['two'] ['name'] = 4; 更改map2 ['two'] ['name']之后,map1也进行了更改 (2认同)
  • 请记住,如果您知道原始“List”的类型,“List&lt;E&gt;.of()”可能会更好。 (2认同)

小智 33

如果您使用的是 dart > 2.3.0,则可以使用扩展运算符,例如:

List<int> a = [1,2,3];
List<int> b = [...a]; // copy of a
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不会克隆对象列表。该列表将包含参考文献。 (7认同)
  • 这是一个浅拷贝 (2认同)

Shu*_*mar 33

使用新版本的 dart 克隆地图或列表变得非常容易。您可以尝试使用此方法对 List 和 Map 进行深度克隆。

对于列表

List a = ['x','y', 'z'];
List b = [...a];
Run Code Online (Sandbox Code Playgroud)

对于地图

Map mapA = {"a":"b"};
Map mapB = {...mapA};
Run Code Online (Sandbox Code Playgroud)

对于套装

Set setA = {1,2,3,};
Set setB = {...setA};
Run Code Online (Sandbox Code Playgroud)

我希望有人觉得这有帮助。

  • 这不会克隆对象列表!该列表将包含对每个对象的引用。https://dartpad.dartlang.org/?41547dffef02aeb34e14c1123adf72a (10认同)
  • 错误的 !仅复制非对象数据。往上看 (3认同)
  • 是的,这只是一个吞咽副本。每个对象项的引用将是相同的。 (3认同)
  • @funder7 是的,这也适用于 Set。设置set1 = {1,2,3,}; 设置 s = {...set1}; (2认同)

Nir*_*ane 15

方法一:推荐

要克隆多维(嵌套) List 或 Map,请使用 json.decode() 和 json.encode()

List newList = json.decode(json.encode(oldList));
Map newMap = json.decode(json.encode(oldList));
Run Code Online (Sandbox Code Playgroud)

方法2:

List newList = [...oldList];
Map newMap = {...oldMap}
Run Code Online (Sandbox Code Playgroud)

方法3:

List newList = List.from(oldList);
Map newMap = Map.from(oldMap);
Run Code Online (Sandbox Code Playgroud)

方法4:

List newList = List.of(oldList);
Map newMap = Map.of(oldMap);
Run Code Online (Sandbox Code Playgroud)

方法5:

List newList = List.unmodifiable(oldList);
Map newMap = Map.unmodifiable(oldMap);
Run Code Online (Sandbox Code Playgroud)

更多参考资料:

https://www.kindacode.com/article/how-to-clone-a-list-or-map-in-dart-and-flutter/ https://coflutter.com/dart-flutter-how-to-克隆复制列表/


kar*_*our 11

对于深拷贝(克隆),您可以使用:

Map<String, dynamic> src = {'a': 123, 'b': 456};
Map<String, dynamic> copy = json.decode(json.encode(src));
Run Code Online (Sandbox Code Playgroud)

但可能会有一些对性能的担忧。

  • @qiAlex,这是显而易见的,但这是有人可以选择的一种方式,伙计。很多时候,当您想要克隆和对象时,它会包含基元。意思是克隆一个函数! (4认同)
  • 我不完全理解为什么这个回复被否决了,因为它确实有一些优势。是的,会有一些性能问题,但它确实会在内部复制列表,而不仅仅是复制指向它们的链接。所以我会给你投一票 (2认同)

ste*_*iel 8

对于列表和集合,我通常使用

List<String> clone = []..addAll(originalList);
Run Code Online (Sandbox Code Playgroud)

需要说明的,如@kzhdev提到,是addAll()from()

[不要]真正地克隆。他们在新的地图/列表/集合中添加参考。

我通常可以,但是我会记住这一点。


小智 7

此解决方案应该有效:

  List list1 = [1,2,3,4]; 

  List list2 = list1.map((element)=>element).toList();
Run Code Online (Sandbox Code Playgroud)

它用于列表,但对于地图等应该相同,如果最后是列表,请记住添加到列表


Man*_*ruw 7

Map.from()仅适用于一维地图。

要在 dart 中不参考复制多维地图,请使用以下方法


    Map<keyType, valueType> copyDeepMap( Map<keyType, valueType> map )
    {
        Map<keyType, valueType> newMap = {};

        map.forEach
        (
            (key, value)
            {
                newMap[key] =( value is Map ) ? copyDeepMap(value) : value ;
            }
        );

        return newMap;
    }

Run Code Online (Sandbox Code Playgroud)