# HashSet<E> constructor

HashSet<E>({bool equals(E e1, E e2), int hashCode(E e), bool isValidKey(dynamic potentialKey) })

Create a hash set using the provided `equals` as equality.

The provided `equals` must define a stable equivalence relation, and `hashCode` must be consistent with `equals`. If the `equals` or `hashCode` methods won't work on all objects, but only on some instances of E, the `isValidKey` predicate can be used to restrict the keys that the functions are applied to. Any key for which `isValidKey` returns false is automatically assumed to not be in the set when asking `contains`.

If `equals` or `hashCode` are omitted, the set uses the elements' intrinsic Object.== and Object.hashCode.

If you supply one of `equals` and `hashCode`, you should generally also to supply the other.

If the supplied `equals` or `hashCode` functions won't work on all `E` objects, and the map will be used in a setting where a non-`E` object is passed to, e.g., `contains`, then the `isValidKey` function should also be supplied.

If `isValidKey` is omitted, it defaults to testing if the object is an `E` instance. That means that:

    new HashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
                     hashCode: (int e) => e % 5)

does not need an `isValidKey` argument, because it defaults to only accepting `int` values which are accepted by both `equals` and `hashCode`.

If neither `equals`, `hashCode`, nor `isValidKey` is provided, the default `isValidKey` instead accepts all values. The default equality and hashcode operations are assumed to work on all objects.

Likewise, if `equals` is identical, `hashCode` is identityHashCode and `isValidKey` is omitted, the resulting set is identity based, and the `isValidKey` defaults to accepting all keys. Such a map can be created directly using HashSet.identity.

## Implementation

    external factory HashSet(
        {bool equals(E e1, E e2),
        int hashCode(E e),
        bool isValidKey(potentialKey)});