KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibm > icu > impl > CollectionUtilities


1 //##header 1189099962000 FOUNDATION
2
/*
3  *******************************************************************************
4  * Copyright (C) 1996-2006, International Business Machines Corporation and *
5  * others. All Rights Reserved. *
6  *******************************************************************************
7  */

8 package com.ibm.icu.impl;
9
10 import java.util.ArrayList JavaDoc;
11 import java.util.Collection JavaDoc;
12 import java.util.Comparator JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.SortedSet JavaDoc;
18
19 //#ifndef FOUNDATION
20
//##import java.util.regex.Matcher;
21
//#endif
22

23 import com.ibm.icu.text.Transliterator;
24 import com.ibm.icu.text.UTF16;
25 import com.ibm.icu.text.UnicodeSet;
26 import com.ibm.icu.text.UnicodeSetIterator;
27
28 /**
29  * Utilities that ought to be on collections, but aren't
30  */

31 public final class CollectionUtilities {
32     
33     public static String JavaDoc join(Object JavaDoc[] array, String JavaDoc separator) {
34         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
35         for (int i = 0; i < array.length; ++i) {
36             if (i != 0) result.append(separator);
37             result.append(array[i]);
38         }
39         return result.toString();
40     }
41
42     public static String JavaDoc join(Collection JavaDoc collection, String JavaDoc separator) {
43         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
44         boolean first = true;
45         for (Iterator JavaDoc it = collection.iterator(); it.hasNext();) {
46             if (first) first = false;
47             else result.append(separator);
48             result.append(it.next());
49         }
50         return result.toString();
51     }
52
53     /**
54      * Utility like Arrays.asList()
55      */

56     public static Map JavaDoc asMap(Object JavaDoc[][] source, Map JavaDoc target, boolean reverse) {
57         int from = 0, to = 1;
58         if (reverse) {
59             from = 1; to = 0;
60         }
61         for (int i = 0; i < source.length; ++i) {
62             target.put(source[i][from], source[i][to]);
63         }
64         return target;
65     }
66     
67     public static Collection JavaDoc addAll(Iterator JavaDoc source, Collection JavaDoc target) {
68         while (source.hasNext()) {
69             target.add(source.next());
70         }
71         return target; // for chaining
72
}
73     
74     public static int size(Iterator JavaDoc source) {
75         int result = 0;
76         while (source.hasNext()) {
77             source.next();
78             ++result;
79         }
80         return result;
81     }
82     
83
84     public static Map JavaDoc asMap(Object JavaDoc[][] source) {
85         return asMap(source, new HashMap JavaDoc(), false);
86     }
87     
88     /**
89      * Utility that ought to be on Map
90      */

91     public static Map JavaDoc removeAll(Map JavaDoc m, Collection JavaDoc itemsToRemove) {
92         for (Iterator JavaDoc it = itemsToRemove.iterator(); it.hasNext();) {
93             Object JavaDoc item = it.next();
94             m.remove(item);
95         }
96         return m;
97     }
98     
99     public Object JavaDoc getFirst(Collection JavaDoc c) {
100         Iterator JavaDoc it = c.iterator();
101         if (!it.hasNext()) return null;
102         return it.next();
103     }
104     
105     public static Object JavaDoc getBest(Collection JavaDoc c, Comparator JavaDoc comp, int direction) {
106         Iterator JavaDoc it = c.iterator();
107         if (!it.hasNext()) return null;
108         Object JavaDoc bestSoFar = it.next();
109         if (direction < 0) {
110             while (it.hasNext()) {
111                 Object JavaDoc item = it.next();
112                 int compValue = comp.compare(item, bestSoFar);
113                 if (comp.compare(item, bestSoFar) < 0) {
114                     bestSoFar = item;
115                 }
116             }
117         } else {
118             while (it.hasNext()) {
119                 Object JavaDoc item = it.next();
120                 int compValue = comp.compare(item, bestSoFar);
121                 if (comp.compare(item, bestSoFar) > 0) {
122                     bestSoFar = item;
123                 }
124             }
125         }
126         return bestSoFar;
127     }
128     
129     public interface ObjectMatcher {
130         /**
131          * Must handle null, never throw exception
132          */

133         boolean matches(Object JavaDoc o);
134     }
135     
136     public static class InverseMatcher implements ObjectMatcher {
137         ObjectMatcher other;
138         public ObjectMatcher set(ObjectMatcher toInverse) {
139             other = toInverse;
140             return this;
141         }
142         public boolean matches(Object JavaDoc value) {
143             return !other.matches(value);
144         }
145     }
146
147     public static Collection JavaDoc removeAll(Collection JavaDoc c, ObjectMatcher f) {
148         for (Iterator JavaDoc it = c.iterator(); it.hasNext();) {
149             Object JavaDoc item = it.next();
150             if (f.matches(item)) it.remove();
151         }
152         return c;
153     }
154     
155     public static Collection JavaDoc retainAll(Collection JavaDoc c, ObjectMatcher f) {
156         for (Iterator JavaDoc it = c.iterator(); it.hasNext();) {
157             Object JavaDoc item = it.next();
158             if (!f.matches(item)) it.remove();
159         }
160         return c;
161     }
162     
163     public static boolean containsSome(Collection JavaDoc a, Collection JavaDoc b) {
164         // fast paths
165
if (a.size() == 0 || b.size() == 0) return false;
166         if (a == b) return true; // must test after size test.
167

168         if (a instanceof SortedSet JavaDoc && b instanceof SortedSet JavaDoc) {
169             SortedSet JavaDoc aa = (SortedSet JavaDoc) a;
170             SortedSet JavaDoc bb = (SortedSet JavaDoc) b;
171             aa.containsAll(null);
172             Comparator JavaDoc bbc = bb.comparator();
173             Comparator JavaDoc aac = aa.comparator();
174             if (bbc == null) {
175                 if (aac == null) {
176                     Iterator JavaDoc ai = aa.iterator();
177                     Iterator JavaDoc bi = bb.iterator();
178                     Comparable JavaDoc ao = (Comparable JavaDoc) ai.next(); // these are ok, since the sizes are != 0
179
Comparable JavaDoc bo = (Comparable JavaDoc) bi.next();
180                     while (true) {
181                         int rel = ao.compareTo(bo);
182                         if (rel < 0) {
183                             if (!ai.hasNext()) return false;
184                             ao = (Comparable JavaDoc) ai.next();
185                         } else if (rel > 0) {
186                             if (!bi.hasNext()) return false;
187                             bo = (Comparable JavaDoc) bi.next();
188                         } else {
189                                 return true;
190                         }
191                     }
192                 }
193             } else if (bbc.equals(a)) {
194                 Iterator JavaDoc ai = aa.iterator();
195                 Iterator JavaDoc bi = bb.iterator();
196                 Object JavaDoc ao = ai.next(); // these are ok, since the sizes are != 0
197
Object JavaDoc bo = bi.next();
198                 while (true) {
199                     int rel = aac.compare(ao, bo);
200                     if (rel < 0) {
201                         if (!ai.hasNext()) return false;
202                         ao = ai.next();
203                     } else if (rel > 0) {
204                         if (!bi.hasNext()) return false;
205                         bo = bi.next();
206                     } else {
207                         return true;
208                     }
209                 }
210             }
211         }
212         for (Iterator JavaDoc it = a.iterator(); it.hasNext();) {
213             if (b.contains(it.next())) return true;
214         }
215         return false;
216     }
217     
218     public static boolean containsAll(Collection JavaDoc a, Collection JavaDoc b) {
219         // fast paths
220
if (a == b) return true;
221         if (b.size() == 0) return true;
222         if (a.size() == 0) return false;
223
224         if (a instanceof SortedSet JavaDoc && b instanceof SortedSet JavaDoc) {
225             SortedSet JavaDoc aa = (SortedSet JavaDoc) a;
226             SortedSet JavaDoc bb = (SortedSet JavaDoc) b;
227             Comparator JavaDoc bbc = bb.comparator();
228             Comparator JavaDoc aac = aa.comparator();
229             if (bbc == null) {
230                 if (aac == null) {
231                     Iterator JavaDoc ai = aa.iterator();
232                     Iterator JavaDoc bi = bb.iterator();
233                     Comparable JavaDoc ao = (Comparable JavaDoc) ai.next(); // these are ok, since the sizes are != 0
234
Comparable JavaDoc bo = (Comparable JavaDoc) bi.next();
235                     while (true) {
236                         int rel = ao.compareTo(bo);
237                         if (rel == 0) {
238                             if (!bi.hasNext()) return true;
239                             if (!ai.hasNext()) return false;
240                             bo = (Comparable JavaDoc) bi.next();
241                             ao = (Comparable JavaDoc) ai.next();
242                         } else if (rel < 0) {
243                             if (!ai.hasNext()) return false;
244                             ao = (Comparable JavaDoc) ai.next();
245                         } else {
246                             return false;
247                         }
248                     }
249                 }
250             } else if (bbc.equals(a)) {
251                 Iterator JavaDoc ai = aa.iterator();
252                 Iterator JavaDoc bi = bb.iterator();
253                 Object JavaDoc ao = ai.next(); // these are ok, since the sizes are != 0
254
Object JavaDoc bo = bi.next();
255                 while (true) {
256                     int rel = aac.compare(ao, bo);
257                     if (rel == 0) {
258                         if (!bi.hasNext()) return true;
259                         if (!ai.hasNext()) return false;
260                         bo = bi.next();
261                         ao = ai.next();
262                     } else if (rel < 0) {
263                         if (!ai.hasNext()) return false;
264                         ao = ai.next();
265                     } else {
266                         return false;
267                     }
268                 }
269             }
270         }
271         return a.containsAll(b);
272     }
273     
274     public static boolean containsNone(Collection JavaDoc a, Collection JavaDoc b) {
275         return !containsSome(a, b);
276     }
277     
278     /**
279      * Used for results of getContainmentRelation
280      */

281     public static final int
282         ALL_EMPTY = 0,
283         NOT_A_SUPERSET_B = 1,
284         NOT_A_DISJOINT_B = 2,
285         NOT_A_SUBSET_B = 4,
286         NOT_A_EQUALS_B = NOT_A_SUBSET_B | NOT_A_SUPERSET_B,
287         A_PROPER_SUBSET_OF_B = NOT_A_DISJOINT_B | NOT_A_SUPERSET_B,
288         A_PROPER_SUPERSET_B = NOT_A_SUBSET_B | NOT_A_DISJOINT_B,
289         A_PROPER_OVERLAPS_B = NOT_A_SUBSET_B | NOT_A_DISJOINT_B | NOT_A_SUPERSET_B;
290     
291     /**
292      * Assesses all the possible containment relations between collections A and B with one call.<br>
293      * Returns an int with bits set, according to a "Venn Diagram" view of A vs B.<br>
294      * NOT_A_SUPERSET_B: a - b != {}<br>
295      * NOT_A_DISJOINT_B: a * b != {} // * is intersects<br>
296      * NOT_A_SUBSET_B: b - a != {}<br>
297      * Thus the bits can be used to get the following relations:<br>
298      * for A_SUPERSET_B, use (x & CollectionUtilities.NOT_A_SUPERSET_B) == 0<br>
299      * for A_SUBSET_B, use (x & CollectionUtilities.NOT_A_SUBSET_B) == 0<br>
300      * for A_EQUALS_B, use (x & CollectionUtilities.NOT_A_EQUALS_B) == 0<br>
301      * for A_DISJOINT_B, use (x & CollectionUtilities.NOT_A_DISJOINT_B) == 0<br>
302      * for A_OVERLAPS_B, use (x & CollectionUtilities.NOT_A_DISJOINT_B) != 0<br>
303      */

304      public static int getContainmentRelation(Collection JavaDoc a, Collection JavaDoc b) {
305         if (a.size() == 0) {
306             return (b.size() == 0) ? ALL_EMPTY : NOT_A_SUPERSET_B;
307         } else if (b.size() == 0) {
308             return NOT_A_SUBSET_B;
309         }
310         int result = 0;
311         // WARNING: one might think that the following can be short-circuited, by looking at
312
// the sizes of a and b. However, this would fail in general, where a different comparator is being
313
// used in the two collections. Unfortunately, there is no failsafe way to test for that.
314
for (Iterator JavaDoc it = a.iterator(); result != 6 && it.hasNext();) {
315             result |= (b.contains(it.next())) ? NOT_A_DISJOINT_B : NOT_A_SUBSET_B;
316         }
317         for (Iterator JavaDoc it = b.iterator(); (result & 3) != 3 && it.hasNext();) {
318             result |= (a.contains(it.next())) ? NOT_A_DISJOINT_B : NOT_A_SUPERSET_B;
319         }
320         return result;
321     }
322
323     public static String JavaDoc remove(String JavaDoc source, UnicodeSet removals) {
324         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
325         int cp;
326         for (int i = 0; i < source.length(); i += UTF16.getCharCount(cp)) {
327             cp = UTF16.charAt(source, i);
328             if (!removals.contains(cp)) UTF16.append(result, cp);
329         }
330         return result.toString();
331     }
332
333 //#ifndef FOUNDATION
334
//## /**
335
//## * Does one string contain another, starting at a specific offset?
336
//## * @param text
337
//## * @param offset
338
//## * @param other
339
//## * @return
340
//## */
341
//## public static int matchesAt(CharSequence text, int offset, CharSequence other) {
342
//## int len = other.length();
343
//## int i = 0;
344
//## int j = offset;
345
//## for (; i < len; ++i, ++j) {
346
//## char pc = other.charAt(i);
347
//## char tc = text.charAt(j);
348
//## if (pc != tc) return -1;
349
//## }
350
//## return i;
351
//## }
352
//##
353
//## /**
354
//## * Returns the ending offset found by matching characters with testSet, until a position is found that doen't match
355
//## * @param string
356
//## * @param offset
357
//## * @param testSet
358
//## * @return
359
//## */
360
//## public int span(CharSequence string, int offset, UnicodeSet testSet) {
361
//## while (true) {
362
//## int newOffset = testSet.matchesAt(string, offset);
363
//## if (newOffset < 0) return offset;
364
//## }
365
//## }
366
//##
367
//## /**
368
//## * Returns the ending offset found by matching characters with testSet, until a position is found that does match
369
//## * @param string
370
//## * @param offset
371
//## * @param testSet
372
//## * @return
373
//## */
374
//## public int spanNot(CharSequence string, int offset, UnicodeSet testSet) {
375
//## while (true) {
376
//## int newOffset = testSet.matchesAt(string, offset);
377
//## if (newOffset >= 0) return offset;
378
//## ++offset; // try next character position
379
//## // we don't have to worry about surrogates for this.
380
//## }
381
//## }
382
//#endif
383

384     public static String JavaDoc prettyPrint(UnicodeSet uset, boolean compressRanges, UnicodeSet toQuote, Transliterator quoter,
385             Comparator JavaDoc ordering, Comparator JavaDoc spaceComparator) {
386         PrettyPrinter pp = new PrettyPrinter().setCompressRanges(compressRanges);
387         if (toQuote != null) pp.setToQuote(toQuote);
388         if (ordering != null) pp.setOrdering(ordering);
389         if (spaceComparator != null) pp.setSpaceComparator(spaceComparator);
390         return pp.toPattern(uset);
391     }
392     
393     public static class MultiComparator implements Comparator JavaDoc {
394         private Comparator JavaDoc[] comparators;
395     
396         public MultiComparator (Comparator JavaDoc[] comparators) {
397             this.comparators = comparators;
398         }
399     
400         /* Lexigraphic compare. Returns the first difference
401          * @return zero if equal. Otherwise +/- (i+1)
402          * where i is the index of the first comparator finding a difference
403          * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
404          */

405         public int compare(Object JavaDoc arg0, Object JavaDoc arg1) {
406             for (int i = 0; i < comparators.length; ++i) {
407                 int result = comparators[i].compare(arg0, arg1);
408                 if (result == 0) continue;
409                 if (result > 0) return i+1;
410                 return -(i+1);
411             }
412             return 0;
413         }
414     }
415
416     /**
417      * Modifies Unicode set to flatten the strings. Eg [abc{da}] => [abcd]
418      * Returns the set for chaining.
419      * @param exemplar1
420      * @return
421      */

422     public static UnicodeSet flatten(UnicodeSet exemplar1) {
423         UnicodeSet result = new UnicodeSet();
424         boolean gotString = false;
425         for (UnicodeSetIterator it = new UnicodeSetIterator(exemplar1); it.nextRange();) {
426             if (it.codepoint == it.IS_STRING) {
427                 result.addAll(it.string);
428                 gotString = true;
429             } else {
430                 result.add(it.codepoint, it.codepointEnd);
431             }
432         }
433         if (gotString) exemplar1.set(result);
434         return exemplar1;
435     }
436
437     /**
438      * For producing filtered iterators
439      */

440     public static abstract class FilteredIterator implements Iterator JavaDoc {
441         private Iterator JavaDoc baseIterator;
442         private static final Object JavaDoc EMPTY = new Object JavaDoc();
443         private static final Object JavaDoc DONE = new Object JavaDoc();
444         private Object JavaDoc nextObject = EMPTY;
445         public FilteredIterator set(Iterator JavaDoc baseIterator) {
446             this.baseIterator = baseIterator;
447             return this;
448         }
449         public void remove() {
450             throw new UnsupportedOperationException JavaDoc("Doesn't support removal");
451         }
452         public Object JavaDoc next() {
453             Object JavaDoc result = nextObject;
454             nextObject = EMPTY;
455             return result;
456         }
457         public boolean hasNext() {
458             if (nextObject == DONE) return false;
459             if (nextObject != EMPTY) return true;
460             while (baseIterator.hasNext()) {
461                 nextObject = baseIterator.next();
462                 if (isIncluded(nextObject)) {
463                     return true;
464                 }
465             }
466             nextObject = DONE;
467             return false;
468         }
469         abstract public boolean isIncluded(Object JavaDoc item);
470     }
471     
472     public static class PrefixIterator extends FilteredIterator {
473         private String JavaDoc prefix;
474         public PrefixIterator set(Iterator JavaDoc baseIterator, String JavaDoc prefix) {
475             super.set(baseIterator);
476             this.prefix = prefix;
477             return this;
478         }
479         public boolean isIncluded(Object JavaDoc item) {
480             return ((String JavaDoc)item).startsWith(prefix);
481         }
482     }
483     
484 //#ifndef FOUNDATION
485
//## public static class RegexIterator extends FilteredIterator {
486
//## private Matcher matcher;
487
//## public RegexIterator set(Iterator baseIterator, Matcher matcher) {
488
//## super.set(baseIterator);
489
//## this.matcher = matcher;
490
//## return this;
491
//## }
492
//## public boolean isIncluded(Object item) {
493
//## return matcher.reset((String)item).matches();
494
//## }
495
//## }
496
//#endif
497
}
498
Popular Tags