Package com.ibm.icu.impl

Source Code of com.ibm.icu.impl.CollectionUtilities$FilteredIterator

//##header 1189099962000 FOUNDATION
/*
*******************************************************************************
* Copyright (C) 1996-2006, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/
package com.ibm.icu.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;

//#ifndef FOUNDATION
//##import java.util.regex.Matcher;
//#endif

import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetIterator;

/**
* Utilities that ought to be on collections, but aren't
*/
public final class CollectionUtilities {
 
    public static String join(Object[] array, String separator) {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
            if (i != 0) result.append(separator);
            result.append(array[i]);
        }
        return result.toString();
    }

    public static String join(Collection collection, String separator) {
        StringBuffer result = new StringBuffer();
        boolean first = true;
        for (Iterator it = collection.iterator(); it.hasNext();) {
            if (first) first = false;
            else result.append(separator);
            result.append(it.next());
        }
        return result.toString();
    }

  /**
   * Utility like Arrays.asList()
   */
  public static Map asMap(Object[][] source, Map target, boolean reverse) {
    int from = 0, to = 1;
    if (reverse) {
      from = 1; to = 0;
    }
      for (int i = 0; i < source.length; ++i) {
        target.put(source[i][from], source[i][to]);
      }
      return target;
  }
 
  public static Collection addAll(Iterator source, Collection target) {
    while (source.hasNext()) {
      target.add(source.next());
    }
    return target; // for chaining
  }
 
  public static int size(Iterator source) {
    int result = 0;
    while (source.hasNext()) {
      source.next();
      ++result;
    }
    return result;
  }
 

  public static Map asMap(Object[][] source) {
      return asMap(source, new HashMap(), false);
  }
 
  /**
   * Utility that ought to be on Map
   */
  public static Map removeAll(Map m, Collection itemsToRemove) {
      for (Iterator it = itemsToRemove.iterator(); it.hasNext();) {
        Object item = it.next();
        m.remove(item);
      }
      return m;
  }
 
  public Object getFirst(Collection c) {
    Iterator it = c.iterator();
    if (!it.hasNext()) return null;
    return it.next();
  }
 
  public static Object getBest(Collection c, Comparator comp, int direction) {
    Iterator it = c.iterator();
    if (!it.hasNext()) return null;
    Object bestSoFar = it.next();
        if (direction < 0) {
        while (it.hasNext()) {
          Object item = it.next();
                int compValue = comp.compare(item, bestSoFar);
          if (comp.compare(item, bestSoFar) < 0) {
            bestSoFar = item;
                }
        }
        } else {
            while (it.hasNext()) {
                Object item = it.next();
                int compValue = comp.compare(item, bestSoFar);
                if (comp.compare(item, bestSoFar) > 0) {
                    bestSoFar = item;
                }
            }
        }
    return bestSoFar;
  }
 
  public interface ObjectMatcher {
    /**
     * Must handle null, never throw exception
     */
    boolean matches(Object o);
  }
 
    public static class InverseMatcher implements ObjectMatcher {
      ObjectMatcher other;
        public ObjectMatcher set(ObjectMatcher toInverse) {
            other = toInverse;
            return this;
        }
        public boolean matches(Object value) {
            return !other.matches(value);
        }
    }

  public static Collection removeAll(Collection c, ObjectMatcher f) {
    for (Iterator it = c.iterator(); it.hasNext();) {
      Object item = it.next();
      if (f.matches(item)) it.remove();
    }
    return c;
  }
 
  public static Collection retainAll(Collection c, ObjectMatcher f) {
    for (Iterator it = c.iterator(); it.hasNext();) {
      Object item = it.next();
      if (!f.matches(item)) it.remove();
    }
    return c;
  }
   
    public static boolean containsSome(Collection a, Collection b) {
        // fast paths
        if (a.size() == 0 || b.size() == 0) return false;
        if (a == b) return true; // must test after size test.

        if (a instanceof SortedSet && b instanceof SortedSet) {
            SortedSet aa = (SortedSet) a;
            SortedSet bb = (SortedSet) b;
            aa.containsAll(null);
            Comparator bbc = bb.comparator();
            Comparator aac = aa.comparator();
            if (bbc == null) {
              if (aac == null) {
                    Iterator ai = aa.iterator();
                    Iterator bi = bb.iterator();
                    Comparable ao = (Comparable) ai.next(); // these are ok, since the sizes are != 0
                    Comparable bo = (Comparable) bi.next();
                    while (true) {
                        int rel = ao.compareTo(bo);
                        if (rel < 0) {
                            if (!ai.hasNext()) return false;
                            ao = (Comparable) ai.next();
                        } else if (rel > 0) {
                            if (!bi.hasNext()) return false;
                            bo = (Comparable) bi.next();
                        } else {
                                return true
                        }
                    }
                }
            } else if (bbc.equals(a)) {
                Iterator ai = aa.iterator();
                Iterator bi = bb.iterator();
                Object ao = ai.next(); // these are ok, since the sizes are != 0
                Object bo = bi.next();
                while (true) {
                    int rel = aac.compare(ao, bo);
                    if (rel < 0) {
                        if (!ai.hasNext()) return false;
                        ao = ai.next();
                    } else if (rel > 0)  {
                        if (!bi.hasNext()) return false;
                        bo = bi.next();
                    } else {
                        return true
                    }
                }
            }          
        }
      for (Iterator it = a.iterator(); it.hasNext();) {
        if (b.contains(it.next())) return true;
        }
        return false;
    }
   
    public static boolean containsAll(Collection a, Collection b) {
        // fast paths
        if (a == b) return true;
        if (b.size() == 0) return true;
        if (a.size() == 0) return false;

        if (a instanceof SortedSet && b instanceof SortedSet) {
            SortedSet aa = (SortedSet) a;
            SortedSet bb = (SortedSet) b;
            Comparator bbc = bb.comparator();
            Comparator aac = aa.comparator();
            if (bbc == null) {
                if (aac == null) {
                    Iterator ai = aa.iterator();
                    Iterator bi = bb.iterator();
                    Comparable ao = (Comparable) ai.next(); // these are ok, since the sizes are != 0
                    Comparable bo = (Comparable) bi.next();
                    while (true) {
                        int rel = ao.compareTo(bo);
                        if (rel == 0) {
                            if (!bi.hasNext()) return true;
                            if (!ai.hasNext()) return false;
                            bo = (Comparable) bi.next();
                            ao = (Comparable) ai.next();
                        } else if (rel < 0) {
                            if (!ai.hasNext()) return false;
                            ao = (Comparable) ai.next();
                        } else {
                            return false
                        }
                    }
                }
            } else if (bbc.equals(a)) {
                Iterator ai = aa.iterator();
                Iterator bi = bb.iterator();
                Object ao = ai.next(); // these are ok, since the sizes are != 0
                Object bo = bi.next();
                while (true) {
                    int rel = aac.compare(ao, bo);
                    if (rel == 0) {
                        if (!bi.hasNext()) return true;
                        if (!ai.hasNext()) return false;
                        bo = bi.next();
                        ao = ai.next();
                    } else if (rel < 0) {
                        if (!ai.hasNext()) return false;
                        ao = ai.next();
                    } else {
                        return false
                    }
                }
            }          
        }
        return a.containsAll(b);
    }
 
    public static boolean containsNone(Collection a, Collection b) {
        return !containsSome(a, b);
    }
   
    /**
     * Used for results of getContainmentRelation
     */
    public static final int
        ALL_EMPTY = 0,
        NOT_A_SUPERSET_B = 1,
        NOT_A_DISJOINT_B = 2,
        NOT_A_SUBSET_B = 4,
        NOT_A_EQUALS_B = NOT_A_SUBSET_B | NOT_A_SUPERSET_B,
        A_PROPER_SUBSET_OF_B = NOT_A_DISJOINT_B | NOT_A_SUPERSET_B,
        A_PROPER_SUPERSET_B = NOT_A_SUBSET_B | NOT_A_DISJOINT_B,
        A_PROPER_OVERLAPS_B = NOT_A_SUBSET_B | NOT_A_DISJOINT_B | NOT_A_SUPERSET_B;
   
    /**
     * Assesses all the possible containment relations between collections A and B with one call.<br>
     * Returns an int with bits set, according to a "Venn Diagram" view of A vs B.<br>
     * NOT_A_SUPERSET_B: a - b != {}<br>
     * NOT_A_DISJOINT_B: a * b != {}  // * is intersects<br>
     * NOT_A_SUBSET_B: b - a != {}<br>
     * Thus the bits can be used to get the following relations:<br>
     * for A_SUPERSET_B, use (x & CollectionUtilities.NOT_A_SUPERSET_B) == 0<br>
     * for A_SUBSET_B, use (x & CollectionUtilities.NOT_A_SUBSET_B) == 0<br>
     * for A_EQUALS_B, use (x & CollectionUtilities.NOT_A_EQUALS_B) == 0<br>
     * for A_DISJOINT_B, use (x & CollectionUtilities.NOT_A_DISJOINT_B) == 0<br>
     * for A_OVERLAPS_B, use (x & CollectionUtilities.NOT_A_DISJOINT_B) != 0<br>
     */
     public static int getContainmentRelation(Collection a, Collection b) {
        if (a.size() == 0) {
          return (b.size() == 0) ? ALL_EMPTY : NOT_A_SUPERSET_B;
        } else if (b.size() == 0) {
          return NOT_A_SUBSET_B;
        }
        int result = 0;
        // WARNING: one might think that the following can be short-circuited, by looking at
        // the sizes of a and b. However, this would fail in general, where a different comparator is being
        // used in the two collections. Unfortunately, there is no failsafe way to test for that.
        for (Iterator it = a.iterator(); result != 6 && it.hasNext();) {
            result |= (b.contains(it.next())) ? NOT_A_DISJOINT_B : NOT_A_SUBSET_B;
        }
        for (Iterator it = b.iterator(); (result & 3) != 3 && it.hasNext();) {
            result |= (a.contains(it.next())) ? NOT_A_DISJOINT_B : NOT_A_SUPERSET_B;
        }
        return result;
    }

  public static String remove(String source, UnicodeSet removals) {
    StringBuffer result = new StringBuffer();
    int cp;
    for (int i = 0; i < source.length(); i += UTF16.getCharCount(cp)) {
      cp = UTF16.charAt(source, i);
      if (!removals.contains(cp)) UTF16.append(result, cp);
    }
    return result.toString();
  }

//#ifndef FOUNDATION
//##     /**
//##      * Does one string contain another, starting at a specific offset?
//##      * @param text
//##      * @param offset
//##      * @param other
//##      * @return
//##      */
//##        public static int matchesAt(CharSequence text, int offset, CharSequence other) {
//##            int len = other.length();
//##            int i = 0;
//##            int j = offset;
//##            for (; i < len; ++i, ++j) {
//##                char pc = other.charAt(i);
//##                char tc = text.charAt(j);
//##                if (pc != tc) return -1;
//##            }
//##            return i;
//##        }
//##
//##        /**
//##         * Returns the ending offset found by matching characters with testSet, until a position is found that doen't match
//##         * @param string
//##         * @param offset
//##         * @param testSet
//##         * @return
//##         */
//##        public int span(CharSequence string, int offset, UnicodeSet testSet) {
//##            while (true) {
//##                int newOffset = testSet.matchesAt(string, offset);
//##                if (newOffset < 0) return offset;
//##            }
//##        }
//##
//##        /**
//##         * Returns the ending offset found by matching characters with testSet, until a position is found that does match
//##         * @param string
//##         * @param offset
//##         * @param testSet
//##         * @return
//##         */
//##        public int spanNot(CharSequence string, int offset, UnicodeSet testSet) {
//##            while (true) {
//##                int newOffset = testSet.matchesAt(string, offset);
//##                if (newOffset >= 0) return offset;
//##                ++offset; // try next character position
//##                // we don't have to worry about surrogates for this.
//##            }
//##        }
//#endif

    public static String prettyPrint(UnicodeSet uset, boolean compressRanges, UnicodeSet toQuote, Transliterator quoter,
        Comparator ordering, Comparator spaceComparator) {
        PrettyPrinter pp = new PrettyPrinter().setCompressRanges(compressRanges);
        if (toQuote != null) pp.setToQuote(toQuote);
        if (ordering != null) pp.setOrdering(ordering);
        if (spaceComparator != null) pp.setSpaceComparator(spaceComparator);
        return pp.toPattern(uset);
    }
   
    public static class MultiComparator implements Comparator {
        private Comparator[] comparators;
   
        public MultiComparator (Comparator[] comparators) {
            this.comparators = comparators;
        }
   
        /* Lexigraphic compare. Returns the first difference
         * @return zero if equal. Otherwise +/- (i+1)
         * where i is the index of the first comparator finding a difference
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(Object arg0, Object arg1) {
            for (int i = 0; i < comparators.length; ++i) {
                int result = comparators[i].compare(arg0, arg1);
                if (result == 0) continue;
                if (result > 0) return i+1;
                return -(i+1);
            }
            return 0;
        }
    }

    /**
     * Modifies Unicode set to flatten the strings. Eg [abc{da}] => [abcd]
     * Returns the set for chaining.
     * @param exemplar1
     * @return
     */
  public static UnicodeSet flatten(UnicodeSet exemplar1) {
    UnicodeSet result = new UnicodeSet();
    boolean gotString = false;
    for (UnicodeSetIterator it = new UnicodeSetIterator(exemplar1); it.nextRange();) {
      if (it.codepoint == it.IS_STRING) {
        result.addAll(it.string);
        gotString = true;
      } else {
        result.add(it.codepoint, it.codepointEnd);
      }
    }
    if (gotString) exemplar1.set(result);
    return exemplar1;
  }

  /**
   * For producing filtered iterators
   */
  public static abstract class FilteredIterator implements Iterator {
    private Iterator baseIterator;
    private static final Object EMPTY = new Object();
    private static final Object DONE = new Object();
    private Object nextObject = EMPTY;
    public FilteredIterator set(Iterator baseIterator) {
      this.baseIterator = baseIterator;
      return this;
    }
    public void remove() {
      throw new UnsupportedOperationException("Doesn't support removal");
    }
    public Object next() {
      Object result = nextObject;
      nextObject = EMPTY;
      return result;
    }   
    public boolean hasNext() {
      if (nextObject == DONE) return false;
      if (nextObject != EMPTY) return true;
      while (baseIterator.hasNext()) {
        nextObject = baseIterator.next();
        if (isIncluded(nextObject)) {
          return true;
        }
      }
      nextObject = DONE;
      return false;
    }
    abstract public boolean isIncluded(Object item);
  }
 
  public static class PrefixIterator extends FilteredIterator {
    private String prefix;
    public PrefixIterator set(Iterator baseIterator, String prefix) {
      super.set(baseIterator);
      this.prefix = prefix;
      return this;
    }
    public boolean isIncluded(Object item) {
      return ((String)item).startsWith(prefix);
    }
  }
 
//#ifndef FOUNDATION
//##  public static class RegexIterator extends FilteredIterator {
//##    private Matcher matcher;
//##    public RegexIterator set(Iterator baseIterator, Matcher matcher) {
//##      super.set(baseIterator);
//##      this.matcher = matcher;
//##      return this;
//##    }
//##    public boolean isIncluded(Object item) {
//##      return matcher.reset((String)item).matches();
//##    }
//##  }
//#endif
}
TOP

Related Classes of com.ibm.icu.impl.CollectionUtilities$FilteredIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.