1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
package jaggregate; |
7 | |
|
8 | |
import java.io.Serializable; |
9 | |
import java.util.Comparator; |
10 | |
import java.util.NoSuchElementException; |
11 | |
|
12 | |
import static jaggregate.Objects.*; |
13 | |
import static jaggregate.internal.ArgumentChecks.*; |
14 | |
import jaggregate.internal.Casting; |
15 | |
import jaggregate.internal.NonLocalReturnException; |
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
|
23 | |
|
24 | |
|
25 | |
|
26 | |
public abstract class AbstractCollection<E> implements Collection<E> { |
27 | |
|
28 | |
|
29 | |
|
30 | 17484 | protected AbstractCollection() { |
31 | |
|
32 | 17484 | } |
33 | |
|
34 | |
|
35 | |
|
36 | |
|
37 | |
public boolean allSatisfy( final UnaryCondition<? super E> discriminator ) { |
38 | 172 | ensureNotNull( discriminator, DISCRIMINATOR ); |
39 | |
|
40 | |
try { |
41 | 156 | forEachDo( new UnaryFunctor<E, Void>() { |
42 | 383 | public Void evaluate( E argument ) { |
43 | 227 | if ( !discriminator.matches( argument ) ) |
44 | 59 | throw new NonLocalReturnException(); |
45 | 168 | return null; |
46 | |
} |
47 | |
} ); |
48 | |
|
49 | 97 | return true; |
50 | |
} |
51 | 59 | catch ( NonLocalReturnException ignored ) { |
52 | 59 | return false; |
53 | |
} |
54 | |
} |
55 | |
|
56 | |
|
57 | |
|
58 | |
|
59 | |
public boolean anySatisfy( final UnaryCondition<? super E> discriminator ) { |
60 | 172 | ensureNotNull( discriminator, DISCRIMINATOR ); |
61 | |
|
62 | |
try { |
63 | 156 | forEachDo( new UnaryFunctor<E, Void>() { |
64 | 300 | public Void evaluate( E argument ) { |
65 | 144 | if ( discriminator.matches( argument ) ) |
66 | 91 | throw new NonLocalReturnException(); |
67 | 53 | return null; |
68 | |
} |
69 | |
} ); |
70 | |
|
71 | 65 | return false; |
72 | |
} |
73 | 91 | catch ( NonLocalReturnException ignored ) { |
74 | 91 | return true; |
75 | |
} |
76 | |
} |
77 | |
|
78 | |
|
79 | |
|
80 | |
|
81 | |
public Object[] toArray() { |
82 | 41 | return toArray( Object.class ); |
83 | |
} |
84 | |
|
85 | |
|
86 | |
|
87 | |
|
88 | |
public Object[] toArray( Class<? super E> componentClass ) { |
89 | 66 | return Collections.toArray( this, componentClass ); |
90 | |
} |
91 | |
|
92 | |
|
93 | |
|
94 | |
|
95 | |
public Bag<E> toBag() { |
96 | 10 | return new Bag<E>( this ); |
97 | |
} |
98 | |
|
99 | |
|
100 | |
|
101 | |
|
102 | |
public IdentityBag<E> toIdentityBag() { |
103 | 7 | return new IdentityBag<E>( this ); |
104 | |
} |
105 | |
|
106 | |
|
107 | |
|
108 | |
|
109 | |
public IdentitySet<E> toIdentitySet() { |
110 | 7 | return new IdentitySet<E>( this ); |
111 | |
} |
112 | |
|
113 | |
|
114 | |
|
115 | |
|
116 | |
public OrderedCollection<E> toOrderedCollection() { |
117 | 11 | return new OrderedCollection<E>( this ); |
118 | |
} |
119 | |
|
120 | |
|
121 | |
|
122 | |
|
123 | |
public Set<E> toSet() { |
124 | 10 | return new Set<E>( this ); |
125 | |
} |
126 | |
|
127 | |
|
128 | |
|
129 | |
|
130 | |
public SortedCollection<E> toSortedCollection() { |
131 | 12 | return new SortedCollection<E>( ByHashCode.INSTANCE, this ); |
132 | |
} |
133 | |
|
134 | |
|
135 | |
|
136 | |
|
137 | |
public SortedCollection<E> toSortedCollection( Comparator<? super E> comparator ) { |
138 | 10 | return new SortedCollection<E>( comparator, this ); |
139 | |
} |
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
public <R> Collection<R> collect( |
145 | |
final UnaryFunctor<? super E, ? extends R> transformer ) { |
146 | |
|
147 | 118 | ensureNotNull( transformer, TRANSFORMER ); |
148 | |
|
149 | 102 | final ExtensibleCollection<R> results = newEmptyExtensibleResultCollection(); |
150 | 102 | forEachDo( new UnaryFunctor<E, Void>() { |
151 | 478 | public Void evaluate( E argument ) { |
152 | 376 | results.add( transformer.evaluate( argument ) ); |
153 | 376 | return null; |
154 | |
} |
155 | |
} ); |
156 | |
|
157 | 102 | return results; |
158 | |
} |
159 | |
|
160 | |
|
161 | |
|
162 | |
|
163 | |
public E detect( final UnaryCondition<? super E> discriminator ) { |
164 | 142 | ensureNotNull( discriminator, DISCRIMINATOR ); |
165 | |
|
166 | 126 | final Object[] match = new Object[] { null }; |
167 | |
|
168 | |
try { |
169 | 126 | forEachDo( new UnaryFunctor<E, Void>() { |
170 | 238 | public Void evaluate( E argument ) { |
171 | 112 | if ( discriminator.matches( argument ) ) { |
172 | 91 | match[ 0 ] = argument; |
173 | 91 | throw new NonLocalReturnException(); |
174 | |
} |
175 | |
|
176 | 21 | return null; |
177 | |
} |
178 | |
} ); |
179 | |
|
180 | 35 | throw new NoSuchElementException(); |
181 | |
} |
182 | 91 | catch ( NonLocalReturnException ignored ) { |
183 | 91 | return Casting.<E>cast( match[ 0 ] ); |
184 | |
} |
185 | |
} |
186 | |
|
187 | |
|
188 | |
|
189 | |
|
190 | |
public boolean includes( final E target ) { |
191 | |
try { |
192 | 87 | forEachDo( new UnaryFunctor<E, Void>() { |
193 | 285 | public Void evaluate( E argument ) { |
194 | 198 | if ( target.equals( argument ) ) |
195 | 68 | throw new NonLocalReturnException(); |
196 | 130 | return null; |
197 | |
} |
198 | |
} ); |
199 | |
|
200 | 19 | return false; |
201 | |
} |
202 | 68 | catch ( NonLocalReturnException ignored ) { |
203 | 68 | return true; |
204 | |
} |
205 | |
} |
206 | |
|
207 | |
|
208 | |
|
209 | |
|
210 | |
public <R> R inject( R initialValue, |
211 | |
final BinaryFunctor<? super R, ? super E, ? extends R> operation ) { |
212 | |
|
213 | 1019 | ensureNotNull( operation, OPERATION ); |
214 | |
|
215 | 1003 | final Object[] result = new Object[] { initialValue }; |
216 | |
|
217 | 1003 | forEachDo( new UnaryFunctor<E, Void>() { |
218 | 3905 | public Void evaluate( E argument ) { |
219 | 2902 | result[ 0 ] = |
220 | |
operation.evaluate( Casting.<R>cast( result[ 0 ] ), argument ); |
221 | 2902 | return null; |
222 | |
} |
223 | |
} ); |
224 | |
|
225 | 1003 | return Casting.<R>cast( result[ 0 ] ); |
226 | |
} |
227 | |
|
228 | |
|
229 | |
|
230 | |
|
231 | |
public boolean isEmpty() { |
232 | 1129 | return size() == 0; |
233 | |
} |
234 | |
|
235 | |
|
236 | |
|
237 | |
|
238 | |
public int occurrencesOf( final E target ) { |
239 | 371 | final int[] numberOfOccurrences = new int[] { 0 }; |
240 | |
|
241 | 371 | forEachDo( new UnaryFunctor<E, Void>() { |
242 | 2089 | public Void evaluate( E argument ) { |
243 | 1718 | if ( target.equals( argument ) ) |
244 | 323 | ++numberOfOccurrences[ 0 ]; |
245 | 1718 | return null; |
246 | |
} |
247 | |
} ); |
248 | |
|
249 | 371 | return numberOfOccurrences[ 0 ]; |
250 | |
} |
251 | |
|
252 | |
|
253 | |
|
254 | |
|
255 | |
public void rehash() { |
256 | |
|
257 | 30 | } |
258 | |
|
259 | |
|
260 | |
|
261 | |
|
262 | |
public Collection<E> reject( final UnaryCondition<? super E> discriminator ) { |
263 | 145 | ensureNotNull( discriminator, DISCRIMINATOR ); |
264 | |
|
265 | 129 | final ExtensibleCollection<E> rejects = newEmptyExtensibleCollection(); |
266 | |
|
267 | 129 | forEachDo( new UnaryFunctor<E, Void>() { |
268 | 511 | public Void evaluate( E argument ) { |
269 | 382 | if ( !discriminator.matches( argument ) ) |
270 | 125 | rejects.add( argument ); |
271 | 382 | return null; |
272 | |
} |
273 | |
} ); |
274 | |
|
275 | 129 | return rejects; |
276 | |
} |
277 | |
|
278 | |
|
279 | |
|
280 | |
|
281 | |
public Collection<E> select( final UnaryCondition<? super E> discriminator ) { |
282 | 180 | ensureNotNull( discriminator, DISCRIMINATOR ); |
283 | |
|
284 | 164 | final ExtensibleCollection<E> matches = newEmptyExtensibleCollection(); |
285 | |
|
286 | 164 | forEachDo( new UnaryFunctor<E, Void>() { |
287 | 724 | public Void evaluate( E argument ) { |
288 | 560 | if ( discriminator.matches( argument ) ) |
289 | 339 | matches.add( argument ); |
290 | 560 | return null; |
291 | |
} |
292 | |
} ); |
293 | |
|
294 | 164 | return matches; |
295 | |
} |
296 | |
|
297 | |
|
298 | |
|
299 | |
|
300 | |
|
301 | |
|
302 | |
protected abstract ExtensibleCollection<E> newEmptyExtensibleCollection(); |
303 | |
|
304 | |
|
305 | |
|
306 | |
|
307 | |
|
308 | |
|
309 | |
|
310 | |
protected abstract <R> ExtensibleCollection<R> newEmptyExtensibleResultCollection(); |
311 | |
|
312 | 1 | private static class ByHashCode implements Comparator<Object>, Serializable { |
313 | 1 | static final ByHashCode INSTANCE = new ByHashCode(); |
314 | |
private static final long serialVersionUID = -1L; |
315 | |
|
316 | |
public int compare( Object first, Object second ) { |
317 | 58 | int firstHash = nullSafeHashCode( first ); |
318 | 58 | int secondHash = nullSafeHashCode( second ); |
319 | |
|
320 | 58 | if ( firstHash == secondHash ) |
321 | 5 | return 0; |
322 | |
|
323 | 53 | if ( firstHash < secondHash ) |
324 | 40 | return -1; |
325 | |
|
326 | 13 | return 1; |
327 | |
} |
328 | |
} |
329 | |
} |