Clone a List, Map or Set in Dart
Use of clone()
in Java is tricky and questionable1,2. Effectively, clone()
is a copy constructor and for that, the Dart List
, Map
and Set
types each have a named constructor named .from()
that perform a shallow copy; e.g. given these declarations
Map<String, int> numMoons, moreMoons;
numMoons = const <String,int>{ 'Mars' : 2, 'Jupiter' : 27 };
List<String> planets, morePlanets;
you can use .from()
like this:
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');
Note that List.from()
more generally accepts an iterator rather than just a List
.
For sake of completeness, I should mention that the dart:html
Node
class defines a clone() method.
1 J. Bloch, "Effective Java" 2nd Ed., Item 11.
2B. Venners, "Josh Bloch on Design: Copy Constructor versus Cloning", 2002. Referenced from here3. Quote from the article:
If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken. ---J.Bloch
3Dart Issue #6459, clone instance(object).
If you are using dart > 2.3.0, You can use spread operator something like:
List<int> a = [1,2,3];
List<int> b = [...a]; // copy of a
With the new version of dart cloning of a Map or List become quite easy. You can try this method for making a deep clone of List and Map.
For List
List a = ['x','y', 'z'];
List b = [...a];
For Maps
Map mapA = {"a":"b"};
Map mapB = {...mapA};
For Sets
Set setA = {1,2,3,};
Set setB = {...setA};
I hope someone find this helpful.
For lists and sets, I typically use
List<String> clone = []..addAll(originalList);
The caveat, as @kzhdev mentions, is that addAll()
and from()
[Do] not really make a clone. They add a reference in the new Map/List/Set.
That's usually ok with me, but I would keep it in mind.