SplayTreeSet<E> final#
A Set of objects that can be ordered relative to each other.
The set is based on a self-balancing binary tree. It allows most operations in amortized logarithmic time.
Elements of the set are compared using the compare function passed in
the constructor, both for ordering and for equality.
If the set contains only an object a, then set.contains(b)
will return true if and only if compare(a, b) == 0,
and the value of a == b is not even checked.
If the compare function is omitted, the objects are assumed to be
Comparable, and are compared using their
Comparable.compareTo
method.
Non-comparable objects (including null) will not work as an element
in that case.
Note: Do not modify a set (add or remove elements) while an operation is being performed on that set, for example in functions called during a forEach or containsAll call, or while iterating the set.
Do not modify elements in a way which changes their equality (and thus their hash code) while they are in the set. Some specialized kinds of sets may be more permissive with regards to equality, in which case they should document their different behavior and restrictions.
Example:
final planets = SplayTreeSet<String>((a, b) => a.compareTo(b));
To add data to a set, use add or addAll.
planets.add('Neptune');
planets.addAll({'Venus', 'Mars', 'Earth', 'Jupiter'});
print(planets); // {Earth, Jupiter, Mars, Neptune, Venus}
To check if the set is empty, use isEmpty or isNotEmpty. To find the number of elements in the set, use length.
final isEmpty = planets.isEmpty; // false
final length = planets.length; // 5
To check whether the set contains a specific element, use contains.
final marsExists = planets.contains('Mars'); // true
To get element value using index, use elementAt.
final elementAt = planets.elementAt(1);
print(elementAt); // Jupiter
To make a copy of set, use toSet.
final copySet = planets.toSet(); // a `SplayTreeSet` with the same ordering.
print(copySet); // {Earth, Jupiter, Mars, Neptune, Venus}
To remove an element, use remove.
final removedValue = planets.remove('Mars'); // true
print(planets); // {Earth, Jupiter, Neptune, Venus}
To remove multiple elements at the same time, use removeWhere.
planets.removeWhere((element) => element.startsWith('J'));
print(planets); // {Earth, Neptune, Venus}
To removes all elements in this set that do not meet a condition, use retainWhere.
planets.retainWhere((element) => element.contains('Earth'));
print(planets); // {Earth}
To remove all elements and empty the set, use clear.
planets.clear();
print(planets.isEmpty); // true
print(planets); // {}
See also:
- Set is a base-class for collection of objects.
- HashSet the order of the objects in the iterations is not guaranteed.
- LinkedHashSet objects stored based on insertion order.
Mixed-in types
Available Extensions
Constructors#
SplayTreeSet()#
Create a new SplayTreeSet with the given compare function.
If the compare function is omitted, it defaults to Comparable.compare,
and the elements must be comparable.
A provided compare function may not work on all objects. It may not even
work on all E instances.
For operations that add elements to the set, the user is supposed to not pass in objects that don't work with the compare function.
The methods contains,
remove,
lookup,
removeAll
or retainAll
are typed to accept any object(s), and the isValidKey test can used to
filter those objects before handing them to the compare function.
If isValidKey is provided, only values satisfying isValidKey(other)
are compared using the compare method in the methods mentioned above.
If the isValidKey function returns false for an object, it is assumed to
not be in the set.
If omitted, the isValidKey function defaults to checking against the
type parameter: other is E.
Implementation
SplayTreeSet([
int Function(E key1, E key2)? compare,
bool Function(dynamic potentialKey)? isValidKey,
]) : _compare = compare ?? _defaultCompare<E>(),
_validKey = isValidKey;
SplayTreeSet.from() factory#
Creates a SplayTreeSet
that contains all elements.
The set works as if created by SplayTreeSet<E>(compare, isValidKey).
All the elements should be instances of E and valid arguments to
compare.
The elements iterable itself may have any element type, so this
constructor can be used to down-cast a Set, for example as:
Set<SuperType> superSet = ...;
Set<SubType> subSet =
SplayTreeSet<SubType>.from(superSet.whereType<SubType>());
Example:
final numbers = <num>[20, 30, 10];
final setFrom = SplayTreeSet<int>.from(numbers);
print(setFrom); // {10, 20, 30}
Implementation
factory SplayTreeSet.from(
Iterable elements, [
int Function(E key1, E key2)? compare,
bool Function(dynamic potentialKey)? isValidKey,
]) {
if (elements is Iterable<E>) {
return SplayTreeSet<E>.of(elements, compare, isValidKey);
}
SplayTreeSet<E> result = SplayTreeSet<E>(compare, isValidKey);
for (var element in elements) {
result.add(element as dynamic);
}
return result;
}
SplayTreeSet.of() factory#
Creates a SplayTreeSet
from elements.
The set works as if created by new SplayTreeSet<E>(compare, isValidKey).
All the elements should be valid as arguments to the compare function.
Example:
final baseSet = <int>{1, 2, 3};
final setOf = SplayTreeSet<num>.of(baseSet);
print(setOf); // {1, 2, 3}
Implementation
factory SplayTreeSet.of(
Iterable<E> elements, [
int Function(E key1, E key2)? compare,
bool Function(dynamic potentialKey)? isValidKey,
]) => SplayTreeSet(compare, isValidKey)..addAll(elements);
Properties#
first no setter override#
The first element.
Throws a StateError if
this is empty.
Otherwise returns the first element in the iteration order,
equivalent to this.elementAt(0).
Implementation
E get first {
final root = _root;
if (root == null) throw IterableElementError.noElement();
return (_root = _splayMin(root)).key;
}
firstOrNull extension no setter#
The first element of this iterator, or null if the iterable is empty.
Available on Iterable<E>, provided by the IterableExtensions<T> extension
Implementation
T? get firstOrNull {
var iterator = this.iterator;
if (iterator.moveNext()) return iterator.current;
return null;
}
hashCode no setter inherited#
The hash code for this object.
A hash code is a single integer which represents the state of the object that affects operator == comparisons.
All objects have hash codes. The default hash code implemented by Object represents only the identity of the object, the same way as the default operator == implementation only considers objects equal if they are identical (see identityHashCode).
If operator == is overridden to use the object state instead, the hash code must also be changed to represent that state, otherwise the object cannot be used in hash based data structures like the default Set and Map implementations.
Hash codes must be the same for objects that are equal to each other according to operator ==. The hash code of an object should only change if the object changes in a way that affects equality. There are no further requirements for the hash codes. They need not be consistent between executions of the same program and there are no distribution guarantees.
Objects that are not equal are allowed to have the same hash code. It is even technically allowed that all instances have the same hash code, but if clashes happen too often, it may reduce the efficiency of hash-based data structures like HashSet or HashMap.
If a subclass overrides hashCode, it should override the operator == operator as well to maintain consistency.
Inherited from Object.
Implementation
external int get hashCode;
indexed extension no setter#
Pairs of elements of the indices and elements of this iterable.
The elements are (0, this.first) through
(this.length - 1, this.last), in index/iteration order.
Available on Iterable<E>, provided by the IterableExtensions<T> extension
Implementation
@pragma('vm:prefer-inline')
Iterable<(int, T)> get indexed => IndexedIterable<T>(this, 0);
isEmpty no setter override#
Whether this collection has no elements.
May be computed by checking if iterator.moveNext() returns false.
Example:
final emptyList = <int>[];
print(emptyList.isEmpty); // true;
print(emptyList.iterator.moveNext()); // false
Implementation
bool get isEmpty => _root == null;
isNotEmpty no setter override#
Whether this collection has at least one element.
May be computed by checking if iterator.moveNext() returns true.
Example:
final numbers = <int>{1, 2, 3};
print(numbers.isNotEmpty); // true;
print(numbers.iterator.moveNext()); // true
Implementation
bool get isNotEmpty => _root != null;
iterator no setter override#
A new Iterator
that allows iterating the elements of this Iterable.
Iterable classes may specify the iteration order of their elements (for example List always iterate in index order), or they may leave it unspecified (for example a hash-based Set may iterate in any order).
Each time iterator is read, it returns a new iterator,
which can be used to iterate through all the elements again.
The iterators of the same iterable can be stepped through independently,
but should return the same elements in the same order,
as long as the underlying collection isn't changed.
Modifying the collection may cause new iterators to produce different elements, and may change the order of existing elements. A List specifies its iteration order precisely, so modifying the list changes the iteration order predictably. A hash-based Set may change its iteration order completely when adding a new element to the set.
Modifying the underlying collection after creating the new iterator may cause an error the next time Iterator.moveNext is called on that iterator. Any modifiable iterable class should specify which operations will break iteration.
Implementation
Iterator<E> get iterator =>
_SplayTreeKeyIterator<E, _SplayTreeSetNode<E>>(this);
last no setter override#
The last element.
Throws a StateError if
this is empty.
Otherwise may iterate through the elements and returns the last one
seen.
Some iterables may have more efficient ways to find the last element
(for example a list can directly access the last element,
without iterating through the previous ones).
Implementation
E get last {
final root = _root;
if (root == null) throw IterableElementError.noElement();
return (_root = _splayMax(root)).key;
}
lastOrNull extension no setter#
The last element of this iterable, or null if the iterable is empty.
This computation may not be efficient. The last value is potentially found by iterating the entire iterable and temporarily storing every value. The process only iterates the iterable once. If iterating more than once is not a problem, it may be more efficient for some iterables to do:
var lastOrNull = iterable.isEmpty ? null : iterable.last;
Available on Iterable<E>, provided by the IterableExtensions<T> extension
Implementation
T? get lastOrNull {
if (this is EfficientLengthIterable) {
if (isEmpty) return null;
return last;
}
var iterator = this.iterator;
if (!iterator.moveNext()) return null;
T result;
do {
result = iterator.current;
} while (iterator.moveNext());
return result;
}
length no setter override#
The number of elements in this Iterable.
Counting all elements may involve iterating through all elements and can
therefore be slow.
Some iterables have a more efficient way to find the number of elements.
These must override the default implementation of length.
Implementation
int get length => _count;
nonNulls extension no setter#
The non-null elements of this iterable.
The same elements as this iterable, except that null values
are omitted.
Available on Iterable<E>, provided by the NullableIterableExtensions<T extends Object> extension
Implementation
Iterable<T> get nonNulls => NonNullsIterable<T>(this);
runtimeType no setter inherited#
A representation of the runtime type of the object.
Inherited from Object.
Implementation
external Type get runtimeType;
single no setter override#
Checks that this iterable has only one element, and returns that element.
Throws a StateError if
this is empty or has more than one element.
This operation will not iterate past the second element.
Implementation
E get single {
if (_count == 1) return _root!.key;
throw _count == 0
? IterableElementError.noElement()
: IterableElementError.tooMany();
}
singleOrNull extension no setter#
The single element of this iterator, or null.
If the iterator has precisely one element, this is that element.
Otherwise, if the iterator has zero elements, or it has two or more,
the value is null.
Available on Iterable<E>, provided by the IterableExtensions<T> extension
Implementation
T? get singleOrNull {
var iterator = this.iterator;
if (iterator.moveNext()) {
var result = iterator.current;
if (!iterator.moveNext()) return result;
}
return null;
}
wait extension no setter#
Waits for futures in parallel.
Waits for all the futures in this iterable. Returns a list of the resulting values, in the same order as the futures which created them, if all futures are successful.
Similar to Future.wait, but reports errors using a ParallelWaitError, which allows the caller to handle errors and dispose successful results if necessary.
The returned future is completed when all the futures have completed. If any of the futures do not complete, nor does the returned future.
If any future completes with an error,
the returned future completes with a ParallelWaitError.
The ParallelWaitError.values
is a list of the values for
successful futures and null for futures with errors.
The ParallelWaitError.errors
is a list of the same length,
with null values for the successful futures
and an AsyncError
with the error for futures
which completed with an error.
Available on Iterable<E>, provided by the FutureIterable<T> extension
Implementation
Future<List<T>> get wait {
var results = [for (var f in this) _FutureResult<T>(f)];
if (results.isEmpty) return Future<List<T>>.value(<T>[]);
@pragma('vm:awaiter-link')
final c = Completer<List<T>>.sync();
_FutureResult._waitAll(results, (errors) {
if (errors == 0) {
c.complete([for (var r in results) r.value]);
} else {
var errorList = [for (var r in results) r.errorOrNull];
c.completeError(
ParallelWaitError<List<T?>, List<AsyncError?>>(
[for (var r in results) r.valueOrNull],
errorList,
errorCount: errors,
defaultError: errorList.firstWhere(_notNull),
),
);
}
});
return c.future;
}
Methods#
add() override#
Adds value to the set.
Returns true if value (or an equal value) was not yet in the set.
Otherwise returns false and the set is not changed.
Example:
final dateTimes = <DateTime>{};
final time1 = DateTime.fromMillisecondsSinceEpoch(0);
final time2 = DateTime.fromMillisecondsSinceEpoch(0);
// time1 and time2 are equal, but not identical.
assert(time1 == time2);
assert(!identical(time1, time2));
final time1Added = dateTimes.add(time1);
print(time1Added); // true
// A value equal to time2 exists already in the set, and the call to
// add doesn't change the set.
final time2Added = dateTimes.add(time2);
print(time2Added); // false
print(dateTimes); // {1970-01-01 02:00:00.000}
assert(dateTimes.length == 1);
assert(identical(time1, dateTimes.first));
print(dateTimes.length);
Implementation
bool add(E element) => _add(element);
addAll() override#
Adds all elements to this set.
Equivalent to adding each element in elements using add,
but some collections may be able to optimize it.
final characters = <String>{'A', 'B'};
characters.addAll({'A', 'B', 'C'});
print(characters); // {A, B, C}
Implementation
void addAll(Iterable<E> elements) {
for (E element in elements) {
_add(element);
}
}
any() inherited#
Checks whether any element of this iterable satisfies test.
Checks every element in iteration order, and returns true if
any of them make test return true, otherwise returns false.
Returns false if the iterable is empty.
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
var result = numbers.any((element) => element >= 5); // true;
result = numbers.any((element) => element >= 10); // false;
Inherited from SetBase.
Implementation
bool any(bool test(E element)) {
for (E element in this) {
if (test(element)) return true;
}
return false;
}
asNameMap() extension#
Creates a map from the names of enum values to the values.
The collection that this method is called on is expected to have
enums with distinct names, like the values list of an enum class.
Only one value for each name can occur in the created map,
so if two or more enum values have the same name (either being the
same value, or being values of different enum type), at most one of
them will be represented in the returned map.
Available on Iterable<E>, provided by the EnumByName<T extends Enum> extension
Implementation
Map<String, T> asNameMap() => <String, T>{
for (var value in this) value._name: value,
};
byName() extension#
Finds the enum value in this list with name name.
Goes through this collection looking for an enum with
name name, as reported by EnumName.name.
Returns the first value with the given name. Such a value must be found.
Available on Iterable<E>, provided by the EnumByName<T extends Enum> extension
Implementation
T byName(String name) {
for (var value in this) {
if (value._name == name) return value;
}
throw ArgumentError.value(name, "name", "No enum value with that name");
}
cast() override#
A view of this iterable as an iterable of R instances.
If this iterable only contains instances of R, all operations
will work correctly. If any operation tries to access an element
that is not an instance of R, the access will throw instead.
When the returned iterable creates a new object that depends on
the type R, e.g., from toList, it will have exactly the type
R.
Implementation
Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newSet);
clear() override#
Removes all elements from the set.
final characters = <String>{'A', 'B', 'C'};
characters.clear(); // {}
Implementation
void clear() {
_clear();
}
contains() override#
Whether the collection contains an element equal to element.
This operation will check each element in order for being equal to
element, unless it has a more efficient way to find an element
equal to element.
Stops iterating on the first equal element.
The equality used to determine whether element is equal to an element of
the iterable defaults to the Object.==
of the element.
Some types of iterable may have a different equality used for its elements.
For example, a Set
may have a custom equality
(see Set.identity) that its
contains uses.
Likewise the Iterable returned by a Map.keys
call
should use the same equality that the Map uses for keys.
Example:
final gasPlanets = <int, String>{1: 'Jupiter', 2: 'Saturn'};
final containsOne = gasPlanets.keys.contains(1); // true
final containsFive = gasPlanets.keys.contains(5); // false
final containsJupiter = gasPlanets.values.contains('Jupiter'); // true
final containsMercury = gasPlanets.values.contains('Mercury'); // false
Implementation
bool contains(Object? element) => _untypedLookup(element) != null;
containsAll() inherited#
Whether this set contains all the elements of other.
final characters = <String>{'A', 'B', 'C'};
final containsAB = characters.containsAll({'A', 'B'});
print(containsAB); // true
final containsAD = characters.containsAll({'A', 'D'});
print(containsAD); // false
Inherited from SetBase.
Implementation
bool containsAll(Iterable<Object?> other) {
for (var o in other) {
if (!contains(o)) return false;
}
return true;
}
difference() override#
Creates a new set with the elements of this that are not in other.
That is, the returned set contains all the elements of this Set
that
are not elements of other according to other.contains.
final characters1 = <String>{'A', 'B', 'C'};
final characters2 = <String>{'A', 'E', 'F'};
final differenceSet1 = characters1.difference(characters2);
print(differenceSet1); // {B, C}
final differenceSet2 = characters2.difference(characters1);
print(differenceSet2); // {E, F}
Implementation
Set<E> difference(Set<Object?> other) => _filter(other, false);
elementAt() inherited#
Returns the indexth element.
The index must be non-negative and less than length.
Index zero represents the first element (so iterable.elementAt(0)
is
equivalent to iterable.first).
May iterate through the elements in iteration order, ignoring the
first index elements and then returning the next.
Some iterables may have a more efficient way to find the element.
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
final elementAt = numbers.elementAt(4); // 6
Inherited from SetBase.
Implementation
E elementAt(int index) {
RangeError.checkNotNegative(index, "index");
var iterator = this.iterator;
var skipCount = index;
while (iterator.moveNext()) {
if (skipCount == 0) return iterator.current;
skipCount--;
}
throw IndexError.withLength(
index,
index - skipCount,
indexable: this,
name: "index",
);
}
elementAtOrNull() extension#
The element at position index of this iterable, or null.
The index is zero based, and must be non-negative.
Returns the result of elementAt(index) if the iterable has
at least index + 1 elements, and null otherwise.
Available on Iterable<E>, provided by the IterableExtensions<T> extension
Implementation
T? elementAtOrNull(int index) {
RangeError.checkNotNegative(index, "index");
if (this is EfficientLengthIterable) {
if (index >= length) return null;
return elementAt(index);
}
var iterator = this.iterator;
do {
if (!iterator.moveNext()) return null;
} while (--index >= 0);
return iterator.current;
}
every() inherited#
Checks whether every element of this iterable satisfies test.
Checks every element in iteration order, and returns false if
any of them make test return false, otherwise returns
true.
Returns true if the iterable is empty.
Example:
final planetsByMass = <double, String>{0.06: 'Mercury', 0.81: 'Venus',
0.11: 'Mars'};
// Checks whether all keys are smaller than 1.
final every = planetsByMass.keys.every((key) => key < 1.0); // true
Inherited from SetBase.
Implementation
bool every(bool f(E element)) {
for (E element in this) {
if (!f(element)) return false;
}
return true;
}
expand() inherited#
Expands each element of this Iterable into zero or more elements.
The resulting Iterable runs through the elements returned
by toElements for each element of this, in iteration order.
The returned Iterable is lazy, and calls
toElements for each element
of this iterable every time the returned iterable is iterated.
Example:
Iterable<int> count(int n) sync* {
for (var i = 1; i <= n; i++) {
yield i;
}
}
var numbers = [1, 3, 0, 2];
print(numbers.expand(count)); // (1, 1, 2, 3, 1, 2)
Equivalent to:
Iterable<T> expand<T>(Iterable<T> toElements(E e)) sync* {
for (var value in this) {
yield* toElements(value);
}
}
Inherited from SetBase.
Implementation
Iterable<T> expand<T>(Iterable<T> f(E element)) =>
ExpandIterable<E, T>(this, f);
firstWhere() inherited#
The first element that satisfies the given predicate test.
Iterates through elements and returns the first to satisfy test.
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
var result = numbers.firstWhere((element) => element < 5); // 1
result = numbers.firstWhere((element) => element > 5); // 6
result =
numbers.firstWhere((element) => element > 10, orElse: () => -1); // -1
If no element satisfies test, the result of invoking the orElse
function is returned.
If orElse is omitted, it defaults to throwing a StateError.
Stops iterating on the first matching element.
Inherited from SetBase.
Implementation
E firstWhere(bool test(E value), {E Function()? orElse}) {
for (E element in this) {
if (test(element)) return element;
}
if (orElse != null) return orElse();
throw IterableElementError.noElement();
}
fold() inherited#
Reduces a collection to a single value by iteratively combining each element of the collection with an existing value
Uses initialValue as the initial value,
then iterates through the elements and updates the value with
each element using the combine function, as if by:
var value = initialValue;
for (E element in this) {
value = combine(value, element);
}
return value;
Example of calculating the sum of an iterable:
final numbers = <double>[10, 2, 5, 0.5];
const initialValue = 100.0;
final result = numbers.fold<double>(
initialValue, (previousValue, element) => previousValue + element);
print(result); // 117.5
Inherited from SetBase.
Implementation
T fold<T>(T initialValue, T combine(T previousValue, E element)) {
var value = initialValue;
for (E element in this) value = combine(value, element);
return value;
}
followedBy() inherited#
Creates the lazy concatenation of this iterable and other.
The returned iterable will provide the same elements as this iterable,
and, after that, the elements of other, in the same order as in the
original iterables.
Example:
var planets = <String>['Earth', 'Jupiter'];
var updated = planets.followedBy(['Mars', 'Venus']);
print(updated); // (Earth, Jupiter, Mars, Venus)
Inherited from SetBase.
Implementation
Iterable<E> followedBy(Iterable<E> other) =>
FollowedByIterable<E>.firstEfficient(this, other);
forEach() inherited#
Invokes action on each element of this iterable in iteration order.
Example:
final numbers = <int>[1, 2, 6, 7];
numbers.forEach(print);
// 1
// 2
// 6
// 7
Inherited from SetBase.
Implementation
void forEach(void f(E element)) {
for (E element in this) f(element);
}
intersection() override#
Creates a new set which is the intersection between this set and other.
That is, the returned set contains all the elements of this Set
that
are also elements of other according to other.contains.
final characters1 = <String>{'A', 'B', 'C'};
final characters2 = <String>{'A', 'E', 'F'};
final intersectionSet = characters1.intersection(characters2);
print(intersectionSet); // {A}
Implementation
Set<E> intersection(Set<Object?> other) => _filter(other, true);
join() inherited#
Converts each element to a String and concatenates the strings.
Iterates through elements of this iterable,
converts each one to a String
by calling Object.toString,
and then concatenates the strings, with the
separator string interleaved between the elements.
Example:
final planetsByMass = <double, String>{0.06: 'Mercury', 0.81: 'Venus',
0.11: 'Mars'};
final joinedNames = planetsByMass.values.join('-'); // Mercury-Venus-Mars
Inherited from SetBase.
Implementation
String join([String separator = ""]) {
Iterator<E> iterator = this.iterator;
if (!iterator.moveNext()) return "";
var first = iterator.current.toString();
if (!iterator.moveNext()) return first;
var buffer = StringBuffer(first);
// TODO(51681): Drop null check when de-supporting pre-2.12 code.
if (separator == null || separator.isEmpty) {
do {
buffer.write(iterator.current);
} while (iterator.moveNext());
} else {
do {
buffer
..write(separator)
..write(iterator.current);
} while (iterator.moveNext());
}
return buffer.toString();
}
lastWhere() inherited#
The last element that satisfies the given predicate test.
An iterable that can access its elements directly may check its
elements in any order (for example a list starts by checking the
last element and then moves towards the start of the list).
The default implementation iterates elements in iteration order,
checks test(element) for each,
and finally returns that last one that matched.
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
var result = numbers.lastWhere((element) => element < 5); // 3
result = numbers.lastWhere((element) => element > 5); // 7
result = numbers.lastWhere((element) => element > 10,
orElse: () => -1); // -1
If no element satisfies test, the result of invoking the orElse
function is returned.
If orElse is omitted, it defaults to throwing a StateError.
Inherited from SetBase.
Implementation
E lastWhere(bool test(E value), {E Function()? orElse}) {
var iterator = this.iterator;
E result;
do {
if (!iterator.moveNext()) {
if (orElse != null) return orElse();
throw IterableElementError.noElement();
}
result = iterator.current;
} while (!test(result));
while (iterator.moveNext()) {
var current = iterator.current;
if (test(current)) result = current;
}
return result;
}
lookup() override#
If an object equal to object is in the set, return it.
Checks whether object is in the set, like contains, and if so,
returns the object in the set, otherwise returns null.
If the equality relation used by the set is not identity,
then the returned object may not be identical to object.
Some set implementations may not be able to implement this method.
If the contains
method is computed,
rather than being based on an actual object instance,
then there may not be a specific object instance representing the
set element.
final characters = <String>{'A', 'B', 'C'};
final containsB = characters.lookup('B');
print(containsB); // B
final containsD = characters.lookup('D');
print(containsD); // null
Implementation
E? lookup(Object? object) => _untypedLookup(object)?.key;
map() inherited#
The current elements of this iterable modified by toElement.
Returns a new lazy Iterable
with elements that are created by
calling toElement on each element of this Iterable
in
iteration order.
The returned iterable is lazy, so it won't iterate the elements of
this iterable until it is itself iterated, and then it will apply
toElement to create one element at a time.
The converted elements are not cached.
Iterating multiple times over the returned Iterable
will invoke the supplied toElement function once per element
for on each iteration.
Methods on the returned iterable are allowed to omit calling toElement
on any element where the result isn't needed.
For example, elementAt
may call toElement only once.
Equivalent to:
Iterable<T> map<T>(T toElement(E e)) sync* {
for (var value in this) {
yield toElement(value);
}
}
Example:
var products = jsonDecode('''
[
{"name": "Screwdriver", "price": 42.00},
{"name": "Wingnut", "price": 0.50}
]
''');
var values = products.map((product) => product['price'] as double);
var totalPrice = values.fold(0.0, (a, b) => a + b); // 42.5.
Inherited from SetBase.
Implementation
Iterable<T> map<T>(T f(E element)) =>
EfficientLengthMappedIterable<E, T>(this, f);
noSuchMethod() inherited#
Invoked when a nonexistent method or property is accessed.
A dynamic member invocation can attempt to call a member which doesn't exist on the receiving object. Example:
dynamic object = 1;
object.add(42); // Statically allowed, run-time error
This invalid code will invoke the noSuchMethod method
of the integer 1 with an Invocation
representing the
.add(42) call and arguments (which then throws).
Classes can override noSuchMethod to provide custom behavior for such invalid dynamic invocations.
A class with a non-default noSuchMethod invocation can also omit implementations for members of its interface. Example:
class MockList<T> implements List<T> {
noSuchMethod(Invocation invocation) {
log(invocation);
super.noSuchMethod(invocation); // Will throw.
}
}
void main() {
MockList().add(42);
}
This code has no compile-time warnings or errors even though
the MockList class has no concrete implementation of
any of the List interface methods.
Calls to List methods are forwarded to noSuchMethod,
so this code will log an invocation similar to
Invocation.method(#add, [42])
and then throw.
If a value is returned from noSuchMethod,
it becomes the result of the original invocation.
If the value is not of a type that can be returned by the original
invocation, a type error occurs at the invocation.
The default behavior is to throw a NoSuchMethodError.
Inherited from Object.
Implementation
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
external dynamic noSuchMethod(Invocation invocation);
reduce() inherited#
Reduces a collection to a single value by iteratively combining elements of the collection using the provided function.
The iterable must have at least one element. If it has only one element, that element is returned.
Otherwise this method starts with the first element from the iterator, and then combines it with the remaining elements in iteration order, as if by:
E value = iterable.first;
iterable.skip(1).forEach((element) {
value = combine(value, element);
});
return value;
Example of calculating the sum of an iterable:
final numbers = <double>[10, 2, 5, 0.5];
final result = numbers.reduce((value, element) => value + element);
print(result); // 17.5
Consider using fold if the iterable can be empty.
Inherited from SetBase.
Implementation
E reduce(E combine(E value, E element)) {
Iterator<E> iterator = this.iterator;
if (!iterator.moveNext()) {
throw IterableElementError.noElement();
}
E value = iterator.current;
while (iterator.moveNext()) {
value = combine(value, iterator.current);
}
return value;
}
remove() override#
Removes value from the set.
Returns true if value was in the set, and false if not.
The method has no effect if value was not in the set.
final characters = <String>{'A', 'B', 'C'};
final didRemoveB = characters.remove('B'); // true
final didRemoveD = characters.remove('D'); // false
print(characters); // {A, C}
Implementation
bool remove(Object? object) {
if (_untypedLookup(object) == null) return false;
_removeRoot();
return true;
}
removeAll() override#
Removes each element of elements from this set.
final characters = <String>{'A', 'B', 'C'};
characters.removeAll({'A', 'B', 'X'});
print(characters); // {C}
Implementation
void removeAll(Iterable<Object?> elements) {
for (Object? element in elements) {
if (_untypedLookup(element) != null) {
_removeRoot();
}
}
}
removeWhere() inherited#
Removes all elements of this set that satisfy test.
final characters = <String>{'A', 'B', 'C'};
characters.removeWhere((element) => element.startsWith('B'));
print(characters); // {A, C}
Inherited from SetBase.
Implementation
void removeWhere(bool test(E element)) {
List<Object?> toRemove = [];
for (E element in this) {
if (test(element)) toRemove.add(element);
}
removeAll(toRemove);
}
retainAll() override#
Removes all elements of this set that are not elements in elements.
Checks for each element of elements whether there is an element in this
set that is equal to it (according to this.contains), and if so, the
equal element in this set is retained, and elements that are not equal
to any element in elements are removed.
final characters = <String>{'A', 'B', 'C'};
characters.retainAll({'A', 'B', 'X'});
print(characters); // {A, B}
Implementation
void retainAll(Iterable<Object?> elements) {
// Build a set with the same sense of equality as this set.
SplayTreeSet<E> retainSet = SplayTreeSet<E>(_compare, _validKey);
final int originalModificationCount = _modificationCount;
for (Object? object in elements) {
if (originalModificationCount != _modificationCount) {
// The iterator should not have side effects.
throw ConcurrentModificationError(this);
}
final root = _untypedLookup(object);
if (root != null) retainSet.add(root.key);
}
// Take over the elements from the retained set, if it differs.
if (retainSet._count != _count) {
_root = retainSet._root;
_count = retainSet._count;
_modificationCount++;
}
}
retainWhere() inherited#
Removes all elements of this set that fail to satisfy test.
final characters = <String>{'A', 'B', 'C'};
characters.retainWhere(
(element) => element.startsWith('B') || element.startsWith('C'));
print(characters); // {B, C}
Inherited from SetBase.
Implementation
void retainWhere(bool test(E element)) {
List<Object?> toRemove = [];
for (E element in this) {
if (!test(element)) toRemove.add(element);
}
removeAll(toRemove);
}
singleWhere() inherited#
The single element that satisfies test.
Checks elements to see if test(element) returns true.
If exactly one element satisfies test, that element is returned.
If more than one matching element is found, throws StateError.
If no matching element is found, returns the result of orElse.
If orElse is omitted, it defaults to throwing a StateError.
Example:
final numbers = <int>[2, 2, 10];
var result = numbers.singleWhere((element) => element > 5); // 10
When no matching element is found, the result of calling orElse is
returned instead.
result = numbers.singleWhere((element) => element == 1,
orElse: () => -1); // -1
There must not be more than one matching element.
result = numbers.singleWhere((element) => element == 2); // Throws Error.
Inherited from SetBase.
Implementation
E singleWhere(bool test(E value), {E Function()? orElse}) {
var iterator = this.iterator;
E result;
do {
if (!iterator.moveNext()) {
if (orElse != null) return orElse();
throw IterableElementError.noElement();
}
result = iterator.current;
} while (!test(result));
while (iterator.moveNext()) {
if (test(iterator.current)) throw IterableElementError.tooMany();
}
return result;
}
skip() inherited#
Creates an Iterable that provides all but the first
count elements.
When the returned iterable is iterated, it starts iterating over this,
first skipping past the initial count elements.
If this has fewer than count elements, then the resulting Iterable is
empty.
After that, the remaining elements are iterated in the same order as
in this iterable.
Some iterables may be able to find later elements without first iterating through earlier elements, for example when iterating a List. Such iterables are allowed to ignore the initial skipped elements.
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
final result = numbers.skip(4); // (6, 7)
final skipAll = numbers.skip(100); // () - no elements.
The count must not be negative.
Inherited from SetBase.
Implementation
Iterable<E> skip(int n) {
return SkipIterable<E>(this, n);
}
skipWhile() inherited#
Creates an Iterable that skips leading elements while test is satisfied.
The filtering happens lazily. Every new Iterator
of the returned
iterable iterates over all elements of this.
The returned iterable provides elements by iterating this iterable,
but skipping over all initial elements where test(element) returns
true. If all elements satisfy test the resulting iterable is empty,
otherwise it iterates the remaining elements in their original order,
starting with the first element for which test(element) returns
false.
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
var result = numbers.skipWhile((x) => x < 5); // (5, 6, 7)
result = numbers.skipWhile((x) => x != 3); // (3, 5, 6, 7)
result = numbers.skipWhile((x) => x != 4); // ()
result = numbers.skipWhile((x) => x.isOdd); // (2, 3, 5, 6, 7)
Inherited from SetBase.
Implementation
Iterable<E> skipWhile(bool test(E value)) {
return SkipWhileIterable<E>(this, test);
}
take() inherited#
Creates a lazy iterable of the count first elements of this iterable.
The returned Iterable may contain fewer than count elements, if this
contains fewer than count elements.
The elements can be computed by stepping through iterator
until count
elements have been seen.
The count must not be negative.
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
final result = numbers.take(4); // (1, 2, 3, 5)
final takeAll = numbers.take(100); // (1, 2, 3, 5, 6, 7)
Inherited from SetBase.
Implementation
Iterable<E> take(int n) {
return TakeIterable<E>(this, n);
}
takeWhile() inherited#
Creates a lazy iterable of the leading elements satisfying test.
The filtering happens lazily. Every new iterator of the returned
iterable starts iterating over the elements of this.
The elements can be computed by stepping through iterator
until an
element is found where test(element) is false. At that point,
the returned iterable stops (its moveNext() returns false).
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
var result = numbers.takeWhile((x) => x < 5); // (1, 2, 3)
result = numbers.takeWhile((x) => x != 3); // (1, 2)
result = numbers.takeWhile((x) => x != 4); // (1, 2, 3, 5, 6, 7)
result = numbers.takeWhile((x) => x.isOdd); // (1)
Inherited from SetBase.
Implementation
Iterable<E> takeWhile(bool test(E value)) {
return TakeWhileIterable<E>(this, test);
}
toList() inherited#
Creates a List containing the elements of this Iterable.
The elements are in iteration order.
The list is fixed-length if growable is false.
Example:
final planets = <int, String>{1: 'Mercury', 2: 'Venus', 3: 'Mars'};
final keysList = planets.keys.toList(growable: false); // [1, 2, 3]
final valuesList =
planets.values.toList(growable: false); // [Mercury, Venus, Mars]
Inherited from SetBase.
Implementation
List<E> toList({bool growable = true}) =>
List<E>.of(this, growable: growable);
toSet() override#
Creates a Set containing the same elements as this iterable.
The set may contain fewer elements than the iterable, if the iterable contains an element more than once, or it contains one or more elements that are equal. The order of the elements in the set is not guaranteed to be the same as for the iterable.
Example:
final planets = <int, String>{1: 'Mercury', 2: 'Venus', 3: 'Mars'};
final valueSet = planets.values.toSet(); // {Mercury, Venus, Mars}
Implementation
Set<E> toSet() => _clone();
toString() override#
A string representation of this object.
Some classes have a default textual representation,
often paired with a static parse function (like int.parse).
These classes will provide the textual representation as
their string representation.
Other classes have no meaningful textual representation
that a program will care about.
Such classes will typically override toString to provide
useful information when inspecting the object,
mainly for debugging or logging.
Implementation
String toString() => Iterable.iterableToFullString(this, '{', '}');
union() override#
Creates a new set which contains all the elements of this set and other.
That is, the returned set contains all the elements of this Set
and
all the elements of other.
final characters1 = <String>{'A', 'B', 'C'};
final characters2 = <String>{'A', 'E', 'F'};
final unionSet1 = characters1.union(characters2);
print(unionSet1); // {A, B, C, E, F}
final unionSet2 = characters2.union(characters1);
print(unionSet2); // {A, E, F, B, C}
Implementation
Set<E> union(Set<E> other) {
return _clone()..addAll(other);
}
where() inherited#
Creates a new lazy Iterable
with all elements that satisfy the
predicate test.
The matching elements have the same order in the returned iterable as they have in iterator.
This method returns a view of the mapped elements.
As long as the returned Iterable
is not iterated over,
the supplied function test will not be invoked.
Iterating will not cache results, and thus iterating multiple times over
the returned Iterable
may invoke the supplied
function test multiple times on the same element.
Example:
final numbers = <int>[1, 2, 3, 5, 6, 7];
var result = numbers.where((x) => x < 5); // (1, 2, 3)
result = numbers.where((x) => x > 5); // (6, 7)
result = numbers.where((x) => x.isEven); // (2, 6)
Inherited from SetBase.
Implementation
Iterable<E> where(bool f(E element)) => WhereIterable<E>(this, f);
whereType() inherited#
Creates a new lazy Iterable
with all elements that have type T.
The matching elements have the same order in the returned iterable as they have in iterator.
This method returns a view of the mapped elements. Iterating will not cache results, and thus iterating multiple times over the returned Iterable may yield different results, if the underlying elements change between iterations.
Inherited from SetBase.
Implementation
Iterable<T> whereType<T>() => WhereTypeIterable<T>(this);
Operators#
operator ==() inherited#
The equality operator.
The default behavior for all Objects is to return true if and
only if this object and other are the same object.
Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:
Total: It must return a boolean for all arguments. It should never throw.
Reflexive: For all objects
o,o == omust be true.-
Symmetric: For all objects
o1ando2,o1 == o2ando2 == o1must either both be true, or both be false. -
Transitive: For all objects
o1,o2, ando3, ifo1 == o2ando2 == o3are true, theno1 == o3must be true.
The method should also be consistent over time, so whether two objects are equal should only change if at least one of the objects was modified.
If a subclass overrides the equality operator, it should override the hashCode method as well to maintain consistency.
Inherited from Object.
Implementation
external bool operator ==(Object other);