OLD | NEW |
---|---|
(Empty) | |
1 part of dart.collection; | |
2 | |
3 class LinkedHashSet<E> extends Collection<E> implements Set<E> { | |
4 static const int _INITIAL_CAPACITY = 8; | |
5 _LinkedHashTable<E> _table; | |
6 | |
7 LinkedHashSet() : _table = new _LinkedHashTable(_INITIAL_CAPACITY); | |
8 | |
9 // Iterable. | |
10 Iterator<E> get iterator => new _LinkedHashTableKeyIterator<E>(_table); | |
11 | |
12 void forEach(void action(E element)) { | |
13 int offset = _table._next(_LinkedHashTable._HEAD_OFFSET); | |
14 int modificationCount = _table._modificationCount; | |
15 while (offset != _LinkedHashTable._HEAD_OFFSET) { | |
16 E key = _table._key(offset); | |
17 action(key); | |
18 _table._checkModification(modificationCount); | |
19 offset = _table._next(offset); | |
20 } | |
21 } | |
22 | |
23 bool get isEmpty => _table._elementCount == 0; | |
24 | |
25 bool contains(Object object) => _table._get(object) >= 0; | |
26 | |
27 E get first { | |
28 int firstOffset = _table._next(_LinkedHashTable._HEAD_OFFSET); | |
29 if (firstOffset == _LinkedHashTable._HEAD_OFFSET) { | |
30 throw new StateError("No elements"); | |
31 } | |
32 return _table._key(firstOffset); | |
33 } | |
34 | |
35 E get last { | |
36 int lastOffset = _table._prev(_LinkedHashTable._HEAD_OFFSET); | |
37 if (lastOffset == _LinkedHashTable._HEAD_OFFSET) { | |
38 throw new StateError("No elements"); | |
39 } | |
40 return _table._key(lastOffset); | |
41 } | |
42 | |
43 E get single { | |
44 int firstOffset = _table._next(_LinkedHashTable._HEAD_OFFSET); | |
45 if (firstOffset == _LinkedHashTable._HEAD_OFFSET) { | |
46 throw new StateError("No elements"); | |
47 } | |
48 int lastOffset = _table._prev(_LinkedHashTable._HEAD_OFFSET); | |
49 if (lastOffset != firstOffset) { | |
50 throw new StateError("Too many elements"); | |
51 } | |
52 return _table._key(firstOffset); | |
53 } | |
54 | |
55 // Collection. | |
56 void add(E element) { | |
57 _table._ensureCapacity(1); | |
58 _table._put(element); | |
59 } | |
60 | |
61 void addAll(Iterable<E> objects) { | |
62 if (objects is Set || objects is List) { | |
floitsch
2013/02/06 10:43:58
I'm not convinced if we should special case, or no
Lasse Reichstein Nielsen
2013/02/08 13:53:01
I think you are right. Reading objects.length will
| |
63 int length = objects.length; | |
64 _table._ensureCapacity(length); | |
65 for (E object in objects) { | |
66 _table._put(object); | |
67 } | |
68 } else { | |
69 for (E object in objects) { | |
70 _table._ensureCapacity(1); | |
71 _table._put(object); | |
72 } | |
73 } | |
74 } | |
75 | |
76 bool remove(Object object) { | |
77 int offset = _table._remove(object); | |
78 return offset >= 0; | |
79 } | |
80 | |
81 void removeAll(Iterable objectsToRemove) { | |
82 for (Object object in objectsToRemove) { | |
83 _table._remove(object); | |
84 } | |
85 } | |
86 | |
87 void retainAll(Iterable objectsToRemove) { | |
88 IterableMixinWorkaround.retainAll(this, objectsToRemove); | |
89 } | |
90 | |
91 void removeMatching(bool test(E element)) { | |
92 int entrySize = _table._entrySize; | |
93 int length = _table._table.length; | |
94 int offset = _table._next(_LinkedHashTable._HEAD_OFFSET); | |
95 while (offset != _LinkedHashTable._HEAD_OFFSET) { | |
96 E key = _table._key(offset); | |
97 int nextOffset = _table._next(offset); | |
98 int modificationCount = _table._modificationCount; | |
99 bool matches = test(key); | |
100 _table._checkModification(modificationCount); | |
101 if (matches) { | |
102 _table._deleteEntry(offset); | |
103 _table._modificationCount++; | |
104 } | |
105 offset = nextOffset; | |
106 } | |
107 } | |
108 | |
109 void retainMatching(bool test(E element)) { | |
floitsch
2013/02/06 10:43:58
removeMatching and retainMatching could share the
Lasse Reichstein Nielsen
2013/02/08 13:53:01
Done.
| |
110 int entrySize = _table._entrySize; | |
111 int length = _table._table.length; | |
112 int offset = _table._next(_LinkedHashTable._HEAD_OFFSET); | |
113 while (offset != _LinkedHashTable._HEAD_OFFSET) { | |
114 E key = _table._key(offset); | |
115 int nextOffset = _table._next(offset); | |
116 int modificationCount = _table._modificationCount; | |
117 bool matches = test(key); | |
118 _table._checkModification(modificationCount); | |
119 if (!matches) { | |
120 _table._deleteEntry(offset); | |
121 _table._modificationCount++; | |
122 } | |
123 offset = nextOffset; | |
124 } | |
125 } | |
126 | |
127 void clear() { | |
128 _table._clear(); | |
129 } | |
130 | |
131 // Set. | |
132 bool isSubsetOf(Collection<E> collection) { | |
133 Set otherSet; | |
134 if (collection is Set) { | |
135 otherSet = collection; | |
136 } else { | |
137 otherSet = collection.toSet(); | |
138 } | |
139 return otherSet.containsAll(this); | |
140 } | |
141 | |
142 bool containsAll(Collection<E> collection) { | |
143 for (E element in collection) { | |
144 if (!this.contains(element)) return false; | |
145 } | |
146 return true; | |
147 } | |
148 | |
149 Set<E> intersection(Collection<E> other) { | |
150 Set<E> result = new HashSet<E>(); | |
floitsch
2013/02/06 10:43:58
new Set.
I think it should be the default Set.
Lasse Reichstein Nielsen
2013/02/08 13:53:01
I'll make it the same typo as this set (which will
| |
151 for (E element in other) { | |
152 if (this.contains(element)) { | |
153 result.add(element); | |
154 } | |
155 } | |
156 return result; | |
157 } | |
158 | |
159 String toString() => Collections.collectionToString(this); | |
160 } | |
OLD | NEW |