This tutorial shows you how to create a Set in Dart with initial values.
Set is a data type for storing unique values. It's quite common to use Set as it can handle duplicate values. Dart supports this data type. In this tutorial, I am going to show you different ways to create a Set in Dart and add initial values during creation.
Define Initial Values
You can create a new Set in Dart by using curly brackets. The initial values can be added between the brackets, with each value separated by comma. If there is any duplicate value, the code will still compile. But you may get a warning in your IDE.
Set<int> values = {10, 20, 30};
If you use any keyword like var
, final
, or const
instead of specifying the variable type, you can define the Set type by adding <Type>
before the curly brackets.
var values = <double>{1, 2, 3};
Create From Existing Set/Iterable
To build a new Set from an existing Set or Iterable, you can use one of the methods provided by Dart.
Using Set.of
Set.of
is a method for creating a new Set from an Iterable.
factory Set.of(Iterable<E> elements)
Example:
var originalTypes = {'grass', 'water', 'fire'};
var newTypes = Set.of(originalSet);
Using Set.from
Set.from
is similar to Set.of
. The difference is you can use it to create a new Set whose element type is the subtype of the original one
factory Set.from(Iterable elements)
Example:
final originalValues = <num>{10, 20, 30, 10};
final newValues = Set.from(originalSet); // return Set<dynamic>
final newValues = Set<int>.from(originalSet); // return Set<int>
Using Set.unmodifiable
If the Set to be created cannot be modified later, you can use the unmodifiable
factory method.
factory Set.unmodifiable(Iterable<E> elements)
Example:
var types = Set.unmodifiable({'grass', 'water', 'fire'});
Using Set.castFrom
Set.castFrom
can be used to create a new Set variable whose element type is a supertype of the existing one. Actually it doesn't copy the source, but only produces a variable that refers to the same Set, with casted element type. Therefore, adding or removing items will affect both source and new variables.
static Set<T> castFrom<S, T>(Set<S> source, {Set<R> Function<R>()? newSet})
For example, we have Animal
class and another class Cow
that extends Animal
.
class Animal {
String name;
Animal({
required this.name,
});
}
class Cow extends Animal {
double power;
Cow({
name,
required this.power,
}) : super(name: name);
}
If there is a Set whose element type is Cow
, you can create a new Set variable whose element type is Animal
. It works because a Cow
instance is also an Animal
instance.
// Below works
Set<Cow> cows = {Cow(name: 'Peeko', power: 100), Cow(name: 'Bigfoot', power: 50)};
Set<Animal> animals = Set.castFrom(cows);
var animals = Set.castFrom<Cow, Animal>(cows);
However, the other way may throw an error when an element is accessed. That's because an Animal
element is not an instance of Cow
.
// Below doesn't work
Set<Animal> animals = {Animal(name: 'Peeko'), Animal(name: 'Bigfoot')};
Set<Cow> cows = Set.castFrom(animals);
print(cows.toList()[0]); // throw type 'Animal' is not a subtype of type 'Cow' in type cast
Summary
This tutorial has some examples of how to create a Set in Dart. The most basic way to define a Set is by using curly brackets where you can put the initial values within the brackets. To copy from an existing Set or Iterable, Dart has some methods that you can use. If the element type is mutable, you have to be careful as modifying an element of the source/original can affect the other. It's recommended to read our tutorial about how to perform deep copy and shallow copy on a Set in Dart.