| 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 |