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 class LinkedHashSet<E> extends _HashSetBase<E> { | 7 class LinkedHashSet<E> extends _HashSetBase<E> { |
8 static const int _INITIAL_CAPACITY = 8; | |
9 _LinkedHashTable<E> _table; | |
10 | 8 |
11 LinkedHashSet() : _table = new _LinkedHashTable(_INITIAL_CAPACITY) { | 9 external LinkedHashSet(); |
12 _table._container = this; | |
13 } | |
14 | 10 |
15 factory LinkedHashSet.from(Iterable<E> iterable) { | 11 factory LinkedHashSet.from(Iterable<E> iterable) { |
16 return new LinkedHashSet<E>()..addAll(iterable); | 12 return new LinkedHashSet<E>()..addAll(iterable); |
17 } | 13 } |
18 | 14 |
19 // Iterable. | 15 // Iterable. |
20 Iterator<E> get iterator => new _LinkedHashTableKeyIterator<E>(_table); | 16 external Iterator<E> get iterator; |
21 | 17 |
22 int get length => _table._elementCount; | 18 external int get length; |
23 | 19 |
24 bool get isEmpty => _table._elementCount == 0; | 20 external bool get isEmpty; |
25 | 21 |
26 bool contains(Object object) => _table._get(object) >= 0; | 22 external bool contains(Object object); |
27 | 23 |
28 void forEach(void action(E element)) { | 24 external void forEach(void action(E element)); |
29 int offset = _table._next(_LinkedHashTable._HEAD_OFFSET); | |
30 int modificationCount = _table._modificationCount; | |
31 while (offset != _LinkedHashTable._HEAD_OFFSET) { | |
32 E key = _table._key(offset); | |
33 action(key); | |
34 _table._checkModification(modificationCount); | |
35 offset = _table._next(offset); | |
36 } | |
37 } | |
38 | 25 |
39 E get first { | 26 external E get first; |
40 int firstOffset = _table._next(_LinkedHashTable._HEAD_OFFSET); | |
41 if (firstOffset == _LinkedHashTable._HEAD_OFFSET) { | |
42 throw new StateError("No elements"); | |
43 } | |
44 return _table._key(firstOffset); | |
45 } | |
46 | 27 |
47 E get last { | 28 external E get last; |
48 int lastOffset = _table._prev(_LinkedHashTable._HEAD_OFFSET); | |
49 if (lastOffset == _LinkedHashTable._HEAD_OFFSET) { | |
50 throw new StateError("No elements"); | |
51 } | |
52 return _table._key(lastOffset); | |
53 } | |
54 | 29 |
55 E get single { | 30 E get single { |
56 int firstOffset = _table._next(_LinkedHashTable._HEAD_OFFSET); | 31 if (length == 1) return first; |
57 if (firstOffset == _LinkedHashTable._HEAD_OFFSET) { | 32 var message = (length == 0) ? "No Elements" : "Too many elements"; |
58 throw new StateError("No elements"); | 33 throw new StateError(message); |
59 } | |
60 int lastOffset = _table._prev(_LinkedHashTable._HEAD_OFFSET); | |
61 if (lastOffset != firstOffset) { | |
62 throw new StateError("Too many elements"); | |
63 } | |
64 return _table._key(firstOffset); | |
65 } | 34 } |
66 | 35 |
67 // Collection. | 36 // Collection. |
68 void _filterWhere(bool test(E element), bool removeMatching) { | 37 external void add(E element); |
69 int entrySize = _table._entrySize; | |
70 int length = _table._table.length; | |
71 int offset = _table._next(_LinkedHashTable._HEAD_OFFSET); | |
72 while (offset != _LinkedHashTable._HEAD_OFFSET) { | |
73 E key = _table._key(offset); | |
74 int nextOffset = _table._next(offset); | |
75 int modificationCount = _table._modificationCount; | |
76 bool shouldRemove = (removeMatching == test(key)); | |
77 _table._checkModification(modificationCount); | |
78 if (shouldRemove) { | |
79 _table._deleteEntry(offset); | |
80 } | |
81 offset = nextOffset; | |
82 } | |
83 _table._checkCapacity(); | |
84 } | |
85 | 38 |
86 void add(E element) { | 39 external void addAll(Iterable<E> objects); |
87 _table._put(element); | |
88 _table._checkCapacity(); | |
89 } | |
90 | 40 |
91 bool remove(Object object) { | 41 external bool remove(Object object); |
92 int offset = _table._remove(object); | |
93 if (offset >= 0) { | |
94 _table._checkCapacity(); | |
95 return true; | |
96 } | |
97 return false; | |
98 } | |
99 | 42 |
100 void removeAll(Iterable objectsToRemove) { | 43 external void removeAll(Iterable objectsToRemove); |
101 for (Object object in objectsToRemove) { | |
102 if (_table._remove(object) >= 0) { | |
103 _table._checkCapacity(); | |
104 } | |
105 } | |
106 } | |
107 | 44 |
108 void retainAll(Iterable objectsToRetain) { | 45 external void removeWhere(bool test(E element)); |
109 Set retainSet; | |
110 if (objectsToRetain is Set) { | |
111 retainSet = objectsToRetain; | |
112 } else { | |
113 retainSet = objectsToRetain.toSet(); | |
114 } | |
115 _filterWhere(retainSet.contains, false); | |
116 } | |
117 | 46 |
118 void removeWhere(bool test(E element)) { | 47 external void retainWhere(bool test(E element)); |
119 _filterWhere(test, true); | |
120 } | |
121 | 48 |
122 retianWhere(bool test(E element)) { | 49 external void clear(); |
123 _filterWhere(test, false); | |
124 } | |
125 | 50 |
126 // Set | 51 // Set. |
127 Set<E> _newSet() => new LinkedHashSet<E>(); | 52 Set<E> _newSet() => new LinkedHashSet<E>(); |
128 } | 53 } |
OLD | NEW |