OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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.core; | 5 part of dart.core; |
6 | 6 |
7 /** | 7 /** |
8 * This class is the public interface of a set. A set is a collection | 8 * This class is the public interface of a set. A set is a collection |
9 * without duplicates. | 9 * without duplicates. |
10 */ | 10 */ |
(...skipping 17 matching lines...) Expand all Loading... |
28 void add(E value); | 28 void add(E value); |
29 | 29 |
30 /** | 30 /** |
31 * Removes [value] from the set. Returns true if [value] was | 31 * Removes [value] from the set. Returns true if [value] was |
32 * in the set. Returns false otherwise. The method has no effect | 32 * in the set. Returns false otherwise. The method has no effect |
33 * if [value] value was not in the set. | 33 * if [value] value was not in the set. |
34 */ | 34 */ |
35 bool remove(E value); | 35 bool remove(E value); |
36 | 36 |
37 /** | 37 /** |
38 * Adds all the elements of the given collection to the set. | 38 * Adds all the elements of the given [iterable] to the set. |
39 */ | 39 */ |
40 void addAll(Collection<E> collection); | 40 void addAll(Iterable<E> iterable); |
41 | 41 |
42 /** | 42 /** |
43 * Removes all the elements of the given collection from the set. | 43 * Removes all the elements of the given collection from the set. |
44 */ | 44 */ |
45 void removeAll(Collection<E> collection); | 45 void removeAll(Iterable<E> iterable); |
46 | 46 |
47 /** | 47 /** |
48 * Returns true if [collection] contains all the elements of this | 48 * Returns true if [collection] contains all the elements of this |
49 * collection. | 49 * collection. |
50 */ | 50 */ |
51 bool isSubsetOf(Collection<E> collection); | 51 bool isSubsetOf(Collection<E> collection); |
52 | 52 |
53 /** | 53 /** |
54 * Returns true if this collection contains all the elements of | 54 * Returns true if this collection contains all the elements of |
55 * [collection]. | 55 * [collection]. |
(...skipping 16 matching lines...) Expand all Loading... |
72 abstract class HashSet<E> extends Set<E> { | 72 abstract class HashSet<E> extends Set<E> { |
73 factory HashSet() => new _HashSetImpl<E>(); | 73 factory HashSet() => new _HashSetImpl<E>(); |
74 | 74 |
75 /** | 75 /** |
76 * Creates a [Set] that contains all elements of [other]. | 76 * Creates a [Set] that contains all elements of [other]. |
77 */ | 77 */ |
78 factory HashSet.from(Iterable<E> other) => new _HashSetImpl<E>.from(other); | 78 factory HashSet.from(Iterable<E> other) => new _HashSetImpl<E>.from(other); |
79 } | 79 } |
80 | 80 |
81 | 81 |
82 class _HashSetImpl<E> implements HashSet<E> { | 82 class _HashSetImpl<E> extends Iterable<E> implements HashSet<E> { |
83 | 83 |
84 _HashSetImpl() { | 84 _HashSetImpl() { |
85 _backingMap = new _HashMapImpl<E, E>(); | 85 _backingMap = new _HashMapImpl<E, E>(); |
86 } | 86 } |
87 | 87 |
88 factory _HashSetImpl.from(Iterable<E> other) { | 88 factory _HashSetImpl.from(Iterable<E> other) { |
89 Set<E> set = new _HashSetImpl<E>(); | 89 Set<E> set = new _HashSetImpl<E>(); |
90 for (final e in other) { | 90 for (final e in other) { |
91 set.add(e); | 91 set.add(e); |
92 } | 92 } |
(...skipping 11 matching lines...) Expand all Loading... |
104 bool contains(E value) { | 104 bool contains(E value) { |
105 return _backingMap.containsKey(value); | 105 return _backingMap.containsKey(value); |
106 } | 106 } |
107 | 107 |
108 bool remove(E value) { | 108 bool remove(E value) { |
109 if (!_backingMap.containsKey(value)) return false; | 109 if (!_backingMap.containsKey(value)) return false; |
110 _backingMap.remove(value); | 110 _backingMap.remove(value); |
111 return true; | 111 return true; |
112 } | 112 } |
113 | 113 |
114 void addAll(Collection<E> collection) { | 114 void addAll(Iterable<E> iterable) { |
115 collection.forEach((E value) { | 115 for (E element in iterable) { |
116 add(value); | 116 add(element); |
117 }); | 117 } |
118 } | 118 } |
119 | 119 |
120 Set<E> intersection(Collection<E> collection) { | 120 Set<E> intersection(Collection<E> collection) { |
121 Set<E> result = new Set<E>(); | 121 Set<E> result = new Set<E>(); |
122 collection.forEach((E value) { | 122 collection.forEach((E value) { |
123 if (contains(value)) result.add(value); | 123 if (contains(value)) result.add(value); |
124 }); | 124 }); |
125 return result; | 125 return result; |
126 } | 126 } |
127 | 127 |
128 bool isSubsetOf(Collection<E> other) { | 128 bool isSubsetOf(Collection<E> other) { |
129 return new Set<E>.from(other).containsAll(this); | 129 return new Set<E>.from(other).containsAll(this); |
130 } | 130 } |
131 | 131 |
132 void removeAll(Collection<E> collection) { | 132 void removeAll(Iterable<E> iterable) { |
133 collection.forEach((E value) { | 133 for (E value in iterable) { |
134 remove(value); | 134 remove(value); |
135 }); | 135 } |
136 } | 136 } |
137 | 137 |
138 bool containsAll(Collection<E> collection) { | 138 bool containsAll(Collection<E> collection) { |
139 return collection.every((E value) { | 139 return collection.every((E value) { |
140 return contains(value); | 140 return contains(value); |
141 }); | 141 }); |
142 } | 142 } |
143 | 143 |
144 void forEach(void f(E element)) { | 144 void forEach(void f(E element)) { |
145 _backingMap.forEach((E key, E value) { | 145 _backingMap.forEach((E key, E value) { |
146 f(key); | 146 f(key); |
147 }); | 147 }); |
148 } | 148 } |
149 | 149 |
150 Set map(f(E element)) { | |
151 Set result = new Set(); | |
152 _backingMap.forEach((E key, E value) { | |
153 result.add(f(key)); | |
154 }); | |
155 return result; | |
156 } | |
157 | |
158 dynamic reduce(dynamic initialValue, | |
159 dynamic combine(dynamic previousValue, E element)) { | |
160 return Collections.reduce(this, initialValue, combine); | |
161 } | |
162 | |
163 Set<E> filter(bool f(E element)) { | |
164 Set<E> result = new Set<E>(); | |
165 _backingMap.forEach((E key, E value) { | |
166 if (f(key)) result.add(key); | |
167 }); | |
168 return result; | |
169 } | |
170 | |
171 bool every(bool f(E element)) { | |
172 Collection<E> keys = _backingMap.keys; | |
173 return keys.every(f); | |
174 } | |
175 | |
176 bool some(bool f(E element)) { | |
177 Collection<E> keys = _backingMap.keys; | |
178 return keys.some(f); | |
179 } | |
180 | |
181 bool get isEmpty { | 150 bool get isEmpty { |
182 return _backingMap.isEmpty; | 151 return _backingMap.isEmpty; |
183 } | 152 } |
184 | 153 |
185 int get length { | 154 int get length { |
186 return _backingMap.length; | 155 return _backingMap.length; |
187 } | 156 } |
188 | 157 |
189 Iterator<E> iterator() { | 158 Iterator<E> get iterator => new _HashSetIterator<E>(this); |
190 return new _HashSetIterator<E>(this); | |
191 } | |
192 | 159 |
193 String toString() { | 160 String toString() { |
194 return Collections.collectionToString(this); | 161 return Collections.collectionToString(this); |
195 } | 162 } |
196 | 163 |
197 // The map backing this set. The associations in this map are all | 164 // The map backing this set. The associations in this map are all |
198 // of the form element -> element. If a value is not in the map, | 165 // of the form element -> element. If a value is not in the map, |
199 // then it is not in the set. | 166 // then it is not in the set. |
200 _HashMapImpl<E, E> _backingMap; | 167 _HashMapImpl<E, E> _backingMap; |
201 } | 168 } |
202 | 169 |
203 class _HashSetIterator<E> implements Iterator<E> { | 170 class _HashSetIterator<E> implements Iterator<E> { |
204 | 171 |
205 // TODO(4504458): Replace set_ with set. | 172 _HashSetIterator(_HashSetImpl<E> set) |
206 _HashSetIterator(_HashSetImpl<E> set_) | 173 : _keysIterator = set._backingMap._keys.iterator; |
207 : _nextValidIndex = -1, | 174 |
208 _entries = set_._backingMap._keys { | 175 E get current { |
209 _advance(); | 176 var result = _keysIterator.current; |
| 177 if (identical(result, _HashMapImpl._DELETED_KEY)) { |
| 178 // TODO(floitsch): improve the error reporting. |
| 179 throw new StateError("Concurrent modification."); |
| 180 } |
| 181 return result; |
210 } | 182 } |
211 | 183 |
212 bool get hasNext { | 184 bool moveNext() { |
213 if (_nextValidIndex >= _entries.length) return false; | 185 bool result; |
214 if (identical(_entries[_nextValidIndex], _HashMapImpl._DELETED_KEY)) { | 186 do { |
215 // This happens in case the set was modified in the meantime. | 187 result = _keysIterator.moveNext(); |
216 // A modification on the set may make this iterator misbehave, | 188 } while (result && |
217 // but we should never return the sentinel. | 189 (_keysIterator.current == null || |
218 _advance(); | 190 identical(_keysIterator.current, _HashMapImpl._DELETED_KEY))); |
219 } | 191 return result; |
220 return _nextValidIndex < _entries.length; | |
221 } | 192 } |
222 | 193 |
223 E next() { | 194 Iterator _keysIterator; |
224 if (!hasNext) { | |
225 throw new StateError("No more elements"); | |
226 } | |
227 E res = _entries[_nextValidIndex]; | |
228 _advance(); | |
229 return res; | |
230 } | |
231 | |
232 void _advance() { | |
233 int length = _entries.length; | |
234 var entry; | |
235 final deletedKey = _HashMapImpl._DELETED_KEY; | |
236 do { | |
237 if (++_nextValidIndex >= length) break; | |
238 entry = _entries[_nextValidIndex]; | |
239 } while ((entry == null) || identical(entry, deletedKey)); | |
240 } | |
241 | |
242 // The entries in the set. May contain null or the sentinel value. | |
243 List<E> _entries; | |
244 | |
245 // The next valid index in [_entries] or the length of [entries_]. | |
246 // If it is the length of [_entries], calling [hasNext] on the | |
247 // iterator will return false. | |
248 int _nextValidIndex; | |
249 } | 195 } |
OLD | NEW |