OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.collection; | 5 part of dart.collection; |
6 | 6 |
7 /** Common parts of [HashSet] and [LinkedHashSet] implementations. */ | 7 /** Common parts of [HashSet] and [LinkedHashSet] implementations. */ |
8 abstract class _HashSetBase<E> extends IterableBase<E> implements Set<E> { | 8 abstract class _HashSetBase<E> extends IterableBase<E> implements Set<E> { |
9 | 9 |
10 // Set. | 10 // Set. |
11 bool containsAll(Iterable<Object> other) { | 11 bool containsAll(Iterable<Object> other) { |
12 for (Object object in other) { | 12 for (Object object in other) { |
13 if (!this.contains(object)) return false; | 13 if (!this.contains(object)) return false; |
14 } | 14 } |
15 return true; | 15 return true; |
16 } | 16 } |
17 | 17 |
18 /** Create a new Set of the same type as this. */ | 18 /** Create a new Set of the same type as this. */ |
19 Set _newSet(); | 19 HashSet<E> _newSet(); |
20 | 20 |
21 Set<E> intersection(Set<Object> other) { | 21 Set<E> intersection(Set<Object> other) { |
22 Set<E> result = _newSet(); | 22 Set<E> result = _newSet(); |
23 if (other.length < this.length) { | 23 if (other.length < this.length) { |
24 for (var element in other) { | 24 for (var element in other) { |
25 if (this.contains(element)) result.add(element); | 25 if (this.contains(element)) result.add(element); |
26 } | 26 } |
27 } else { | 27 } else { |
28 for (E element in this) { | 28 for (E element in this) { |
29 if (other.contains(element)) result.add(element); | 29 if (other.contains(element)) result.add(element); |
(...skipping 12 matching lines...) Expand all Loading... | |
42 if (!other.contains(element)) result.add(element); | 42 if (!other.contains(element)) result.add(element); |
43 } | 43 } |
44 return result; | 44 return result; |
45 } | 45 } |
46 | 46 |
47 void retainAll(Iterable objectsToRetain) { | 47 void retainAll(Iterable objectsToRetain) { |
48 Set retainSet; | 48 Set retainSet; |
49 if (objectsToRetain is Set) { | 49 if (objectsToRetain is Set) { |
50 retainSet = objectsToRetain; | 50 retainSet = objectsToRetain; |
51 } else { | 51 } else { |
52 retainSet = objectsToRetain.toSet(); | 52 retainSet = new HashSet(equals: identical)..addAll(objectsToRetain); |
floitsch
2013/09/12 13:49:12
add comment why identical.
Lasse Reichstein Nielsen
2013/09/18 08:56:36
It was to make it work with both equality sets and
| |
53 } | 53 } |
54 retainWhere(retainSet.contains); | 54 retainWhere(retainSet.contains); |
55 } | 55 } |
56 | 56 |
57 List<E> toList({bool growable: true}) { | |
58 List<E> result = new List<E>()..length = this.length; | |
59 int i = 0; | |
60 for (E element in this) result[i++] = element; | |
61 return result; | |
62 } | |
63 | |
64 Set<E> toSet() => _newSet()..addAll(this); | |
65 | |
57 // TODO(zarah) Remove this, and let it be inherited by IterableBase | 66 // TODO(zarah) Remove this, and let it be inherited by IterableBase |
58 String toString() => IterableMixinWorkaround.toStringIterable(this, '{', '}'); | 67 String toString() => IterableMixinWorkaround.toStringIterable(this, '{', '}'); |
59 } | 68 } |
60 | 69 |
61 /** | 70 /** |
62 * A [HashSet] is a hash-table based [Set] implementation. | 71 * A [HashSet] is a hash-table based [Set] implementation. |
63 * | 72 * |
64 * The elements of a `HashSet` must have consistent [Object.operator==] | 73 * The elements of a `HashSet` must have consistent equality |
65 * and [Object.hashCode] implementations. This means that the `==` operator | 74 * and hashCode implementations. This means that the equals operation |
66 * must define a stable equivalence relation on the elements (reflexive, | 75 * must define a stable equivalence relation on the elements (reflexive, |
67 * anti-symmetric, transitive, and consistent over time), and that `hashCode` | 76 * anti-symmetric, transitive, and consistent over time), and that the hashCode |
68 * must be the same for objects that are considered equal by `==`. | 77 * must consistent with equality, so that the same for objects that are |
78 * considered equal. | |
69 * | 79 * |
70 * The set allows `null` as an element. | 80 * The set allows `null` as an element. |
71 * | 81 * |
72 * Most simple operations on `HashSet` are done in constant time: [add], | 82 * Most simple operations on `HashSet` are done in constant time: [add], |
73 * [contains], [remove], and [length]. | 83 * [contains], [remove], and [length]. |
74 */ | 84 */ |
75 class HashSet<E> extends _HashSetBase<E> { | 85 class HashSet<E> implements Set<E> { |
76 external HashSet(); | 86 /** |
87 * Create a hash set using the provided [equals] as equality. | |
88 * | |
89 * The provided [equals] must define a stable equivalence relation, and | |
90 * [hashCode] must be consistent with [equals]. If the [equals] or [hashCode] | |
91 * methods won't work on all objects, but only to instances of E, the | |
92 * [isValidKey] predicate can be used to restrict the keys that they are | |
93 * applied to. Any key for which [isValidKey] returns false is automatically | |
94 * assumed to not be in the set. | |
95 * | |
96 * If [equals], [hashCode] and [isValidKey] are omitted, the set uses | |
97 * the objects' intrinsic [Object.operator==] and [Object.hashCode]. | |
98 * | |
99 * If [isValidKey] is omitted, it defaults to testing if the object is an | |
100 * [E] instance. | |
101 * | |
102 * If [equals] is [identical], this creates an identity set. Any hashCode | |
103 * is compatible with [identical], and it applies to all objects, so | |
104 * [hashCode] and [isValidKey] can safely be omitted. | |
105 */ | |
106 external factory HashSet({ bool equals(E e1, E e2), | |
107 int hashCode(E e), | |
108 bool isValidKey(potentialKey) }); | |
77 | 109 |
110 /** | |
111 * Create a hash set containing the elements of [iterable]. | |
112 * | |
113 * Creates a hash set as by `new HashSet<E>()` and adds each element of | |
114 * `iterable` to this set in the order they are iterated. | |
115 */ | |
78 factory HashSet.from(Iterable<E> iterable) { | 116 factory HashSet.from(Iterable<E> iterable) { |
79 return new HashSet<E>()..addAll(iterable); | 117 return new HashSet<E>()..addAll(iterable); |
80 } | 118 } |
81 | |
82 // Iterable. | |
83 external Iterator<E> get iterator; | |
84 | |
85 external int get length; | |
86 | |
87 external bool get isEmpty; | |
88 | |
89 external bool get isNotEmpty; | |
90 | |
91 external bool contains(Object object); | |
92 | |
93 // Set. | |
94 external void add(E element); | |
95 | |
96 external void addAll(Iterable<E> objects); | |
97 | |
98 external bool remove(Object object); | |
99 | |
100 external void removeAll(Iterable<Object> objectsToRemove); | |
101 | |
102 external void removeWhere(bool test(E element)); | |
103 | |
104 external void retainWhere(bool test(E element)); | |
105 | |
106 external void clear(); | |
107 | |
108 Set<E> _newSet() => new HashSet<E>(); | |
109 } | 119 } |
OLD | NEW |