| // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| part of dart.core; |
| |
| /** |
| * A collection of objects in which each object can occur only once. |
| * |
| * That is, for each object of the element type, the object is either considered |
| * to be in the set, or to _not_ be in the set. |
| * |
| * Set implementations may consider some elements indistinguishable. These |
| * elements are treated as being the same for any operation on the set. |
| * |
| * The default [Set] implementation, [LinkedHashSet], considers objects |
| * indistinguishable if they are equal with regard to |
| * operator [Object.==]. |
| * |
| * Iterating over elements of a set may be either unordered |
| * or ordered in some way. Examples: |
| * |
| * * A [HashSet] is unordered, which means that its iteration order is |
| * unspecified, |
| * * [LinkedHashSet] iterates in the insertion order of its elements, and |
| * * a sorted set like [SplayTreeSet] iterates the elements in sorted order. |
| * |
| * It is generally not allowed to modify the set (add or remove elements) while |
| * an operation on the set is being performed, for example during a call to |
| * [forEach] or [containsAll]. Nor is it allowed to modify the set while |
| * iterating either the set itself or any [Iterable] that is backed by the set, |
| * such as the ones returned by methods like [where] and [map]. |
| * |
| * It is generally not allowed to modify the equality of elements (and thus not |
| * their hashcode) while they are in the set. Some specialized subtypes may be |
| * more permissive, in which case they should document this behavior. |
| */ |
| abstract class Set<E> extends EfficientLengthIterable<E> { |
| /** |
| * Creates an empty [Set]. |
| * |
| * The created [Set] is a plain [LinkedHashSet]. |
| * As such, it considers elements that are equal (using [operator ==]) to be |
| * indistinguishable, and requires them to have a compatible |
| * [Object.hashCode] implementation. |
| * |
| * The set is equivalent to one created by `new LinkedHashSet<E>()`. |
| */ |
| factory Set() = LinkedHashSet<E>; |
| |
| /** |
| * Creates an empty identity [Set]. |
| * |
| * The created [Set] is a [LinkedHashSet] that uses identity as equality |
| * relation. |
| * |
| * The set is equivalent to one created by `new LinkedHashSet<E>.identity()`. |
| */ |
| factory Set.identity() = LinkedHashSet<E>.identity; |
| |
| /** |
| * Creates a [Set] that contains all [elements]. |
| * |
| * All the [elements] should be instances of [E]. |
| * The `elements` iterable itself can have any type, |
| * so this constructor can be used to down-cast a `Set`, for example as: |
| * |
| * Set<SuperType> superSet = ...; |
| * Set<SubType> subSet = |
| * new Set<SubType>.from(superSet.where((e) => e is SubType)); |
| * |
| * The created [Set] is a [LinkedHashSet]. As such, it considers elements that |
| * are equal (using [operator ==]) to be indistinguishable, and requires them to |
| * have a compatible [Object.hashCode] implementation. |
| * |
| * The set is equivalent to one created by |
| * `new LinkedHashSet<E>.from(elements)`. |
| */ |
| factory Set.from(Iterable elements) = LinkedHashSet<E>.from; |
| |
| /** |
| * Creates a [Set] from [elements]. |
| * |
| * The created [Set] is a [LinkedHashSet]. As such, it considers elements that |
| * are equal (using [operator ==]) to be indistinguishable, and requires them to |
| * have a compatible [Object.hashCode] implementation. |
| * |
| * The set is equivalent to one created by |
| * `new LinkedHashSet<E>.of(elements)`. |
| */ |
| factory Set.of(Iterable<E> elements) = LinkedHashSet<E>.of; |
| |
| /** |
| * Adapts [source] to be a `Set<T>`. |
| * |
| * If [newSet] is provided, it is used to create the new sets returned |
| * by [toSet], [union], and is also used for [intersection] and [difference]. |
| * If [newSet] is omitted, it defaults to creating a new set using the |
| * default [Set] constructor, and [intersection] and [difference] |
| * returns an adapted version of calling the same method on the source. |
| * |
| * Any time the set would produce an element that is not a [T], |
| * the element access will throw. |
| * |
| * Any time a [T] value is attempted added into the adapted set, |
| * the store will throw unless the value is also an instance of [S]. |
| * |
| * If all accessed elements of [source] are actually instances of [T], |
| * and if all elements added to the returned set are actually instance |
| * of [S], |
| * then the returned set can be used as a `Set<T>`. |
| */ |
| static Set<T> castFrom<S, T>(Set<S> source, {Set<R> Function<R>() newSet}) => |
| CastSet<S, T>(source, newSet); |
| |
| /** |
| * Provides a view of this set as a set of [R] instances. |
| * |
| * If this set contains only instances of [R], all read operations |
| * will work correctly. If any operation tries to access an element |
| * that is not an instance of [R], the access will throw instead. |
| * |
| * Elements added to the set (e.g., by using [add] or [addAll]) |
| * must be instance of [R] to be valid arguments to the adding function, |
| * and they must be instances of [E] as well to be accepted by |
| * this set as well. |
| */ |
| Set<R> cast<R>(); |
| /** |
| * Provides an iterator that iterates over the elements of this set. |
| * |
| * The order of iteration is defined by the individual `Set` implementation, |
| * but must be consistent between changes to the set. |
| */ |
| Iterator<E> get iterator; |
| |
| /** |
| * Returns true if [value] is in the set. |
| */ |
| bool contains(Object value); |
| |
| /** |
| * 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: |
| * |
| * var set = new Set(); |
| * var time1 = new DateTime.fromMillisecondsSinceEpoch(0); |
| * var time2 = new DateTime.fromMillisecondsSinceEpoch(0); |
| * // time1 and time2 are equal, but not identical. |
| * Expect.isTrue(time1 == time2); |
| * Expect.isFalse(identical(time1, time2)); |
| * set.add(time1); // => true. |
| * // A value equal to time2 exists already in the set, and the call to |
| * // add doesn't change the set. |
| * set.add(time2); // => false. |
| * Expect.isTrue(set.length == 1); |
| * Expect.isTrue(identical(time1, set.first)); |
| */ |
| bool add(E value); |
| |
| /** |
| * Adds all [elements] to this Set. |
| * |
| * Equivalent to adding each element in [elements] using [add], |
| * but some collections may be able to optimize it. |
| */ |
| void addAll(Iterable<E> elements); |
| |
| /** |
| * Removes [value] from the set. Returns true if [value] was |
| * in the set. Returns false otherwise. The method has no effect |
| * if [value] value was not in the set. |
| */ |
| bool remove(Object value); |
| |
| /** |
| * 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. |
| */ |
| E lookup(Object object); |
| |
| /** |
| * Removes each element of [elements] from this set. |
| */ |
| void removeAll(Iterable<Object> elements); |
| |
| /** |
| * 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. |
| */ |
| void retainAll(Iterable<Object> elements); |
| |
| /** |
| * Removes all elements of this set that satisfy [test]. |
| */ |
| void removeWhere(bool test(E element)); |
| |
| /** |
| * Removes all elements of this set that fail to satisfy [test]. |
| */ |
| void retainWhere(bool test(E element)); |
| |
| /** |
| * Returns whether this Set contains all the elements of [other]. |
| */ |
| bool containsAll(Iterable<Object> other); |
| |
| /** |
| * Returns 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`. |
| */ |
| Set<E> intersection(Set<Object> other); |
| |
| /** |
| * Returns 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]. |
| */ |
| Set<E> union(Set<E> other); |
| |
| /** |
| * Returns 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`. |
| */ |
| Set<E> difference(Set<Object> other); |
| |
| /** |
| * Removes all elements in the set. |
| */ |
| void clear(); |
| |
| /* Creates a [Set] with the same elements and behavior as this `Set`. |
| * |
| * The returned set behaves the same as this set |
| * with regard to adding and removing elements. |
| * It initially contains the same elements. |
| * If this set specifies an ordering of the elements, |
| * the returned set will have the same order. |
| */ |
| Set<E> toSet(); |
| } |