View Javadoc

    1   package net.sourceforge.pmd.util;
    2
    3   import java.util.HashMap;
    4   import java.util.HashSet;
    5   import java.util.Iterator;
    6   import java.util.Map;
    7   import java.util.Set;
    8   import java.util.Map.Entry;
    9
    10  /***
    11   * Generic collection and array-related utility functions.
    12   *
    13   * @author Brian Remedios
    14   * @version $Revision$
    15   */
    16  public class CollectionUtil {
    17
    18  	public static final TypeMap collectionInterfacesByNames = new TypeMap( new Class[] {
    19  		java.util.List.class,
    20  		java.util.Collection.class,
    21  		java.util.Map.class,
    22  		java.util.Set.class,
    23  		});
    24
    25  	public static final TypeMap collectionClassesByNames = new TypeMap( new Class[] {
    26  		java.util.ArrayList.class,
    27  		java.util.LinkedList.class,
    28  		java.util.Vector.class,
    29  		java.util.HashMap.class,
    30  		java.util.LinkedHashMap.class,
    31  		java.util.TreeMap.class,
    32  		java.util.TreeSet.class,
    33  		java.util.HashSet.class,
    34  		java.util.LinkedHashSet.class
    35  		});
    36
    37  	private CollectionUtil() {};
    38
    39  	/***
    40  	 * Returns the collection type if we recognize it by its short name.
    41  	 *
    42  	 * @param shortName String
    43  	 * @return Class
    44  	 */
    45  	public static Class getCollectionTypeFor(String shortName) {
    46  		Class cls = collectionClassesByNames.typeFor(shortName);
    47  		if (cls != null) return cls;
    48
    49  		return collectionInterfacesByNames.typeFor(shortName);
    50  	}
    51
    52  	/***
    53  	 * Return whether we can identify the typeName as a java.util collection class
    54  	 * or interface as specified.
    55  	 *
    56  	 * @param typeName String
    57  	 * @param includeInterfaces boolean
    58  	 * @return boolean
    59  	 */
    60  	public static boolean isCollectionType(String typeName, boolean includeInterfaces) {
    61
    62  		if (collectionClassesByNames.contains(typeName)) return true;
    63
    64  		return includeInterfaces && collectionInterfacesByNames.contains(typeName);
    65  	}
    66
    67      /***
    68       * Return whether we can identify the typeName as a java.util collection class
    69       * or interface as specified.
    70       *
    71       * @param clazzType Class
    72       * @param includeInterfaces boolean
    73       * @return boolean
    74       */
    75      public static boolean isCollectionType(Class clazzType, boolean includeInterfaces) {
    76
    77          if (collectionClassesByNames.contains(clazzType)) {
    78              return true;
    79          }
    80
    81          return includeInterfaces && collectionInterfacesByNames.contains(clazzType);
    82      }
    83
    84      /***
    85       * Returns the items as a populated set.
    86       *
    87       * @param items Object[]
    88       * @return Set
    89       */
    90      public static Set asSet(Object[] items) {
    91
    92      	Set set = new HashSet(items.length);
    93      	for (int i=0; i<items.length; i++) {
    94      		set.add(items[i]);
    95      	}
    96      	return set;
    97      }
    98
    99  	/***
    100 	 * Creates and returns a map populated with the keyValuesSets where
    101 	 * the value held by the tuples are they key and value in that order.
    102 	 *
    103 	 * @param keyValueSets Object[][]
    104 	 * @return Map
    105 	 */
    106 	public static Map mapFrom(Object[][] keyValueSets) {
    107 		Map map = new HashMap(keyValueSets.length);
    108 		for (int i=0; i<keyValueSets.length; i++) {
    109 			map.put(keyValueSets[i][0], keyValueSets[i][1]);
    110 		}
    111 		return map;
    112 	}
    113
    114 	/***
    115 	 * Returns a map based on the source but with the key & values swapped.
    116 	 *
    117 	 * @param source Map
    118 	 * @return Map
    119 	 */
    120 	public static Map invertedMapFrom(Map source) {
    121 		Map map = new HashMap(source.size());
    122 		Iterator iter = source.entrySet().iterator();
    123 		Entry entry;
    124 		while (iter.hasNext()) {
    125 			entry = (Entry)iter.next();
    126 			map.put(entry.getValue(), entry.getKey());
    127 		}
    128 		return map;
    129 	}
    130
    131 	/***
    132 	 * Returns true if the objects are array instances and each of their elements compares
    133 	 * via equals as well.
    134 	 *
    135 	 * @param value Object
    136 	 * @param otherValue Object
    137 	 * @return boolean
    138 	 */
    139 	public static final boolean arraysAreEqual(Object value, Object otherValue) {
    140 		if (value instanceof Object[]) {
    141 			if (otherValue instanceof Object[]) return valuesAreTransitivelyEqual((Object[])value, (Object[])otherValue);
    142 			return false;
    143 		}
    144 		return false;
    145 	}
    146
    147 	/***
    148 	 * Returns whether the arrays are equal by examining each of their elements, even if they are
    149 	 * arrays themselves.
    150 	 *
    151 	 * @param thisArray Object[]
    152 	 * @param thatArray Object[]
    153 	 * @return boolean
    154 	 */
    155 	public static final boolean valuesAreTransitivelyEqual(Object[] thisArray, Object[] thatArray) {
    156 		if (thisArray == thatArray) return true;
    157 		if ((thisArray == null) || (thatArray == null)) return false;
    158 		if (thisArray.length != thatArray.length) return false;
    159 		for (int i = 0; i < thisArray.length; i++) {
    160 			if (!areEqual(thisArray[i], thatArray[i])) return false;	// recurse if req'd
    161 		}
    162 		return true;
    163 	}
    164
    165 	/***
    166 	 * A comprehensive isEqual method that handles nulls and arrays safely.
    167 	 *
    168 	 * @param value Object
    169 	 * @param otherValue Object
    170 	 * @return boolean
    171 	 */
    172 	public static final boolean areEqual(Object value, Object otherValue) {
    173 		if (value == otherValue) return true;
    174 		if (value == null) return false;
    175 		if (otherValue == null) return false;
    176
    177 		if (value.getClass().getComponentType() != null) return arraysAreEqual(value, otherValue);
    178 		return value.equals(otherValue);
    179 	}
    180 }