Java tutorial
//package com.java2s; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; public class Main { /** Constant to avoid repeated object creation */ private static Integer INTEGER_ONE = new Integer(1); /** * Returns a {@link Collection} containing the exclusive disjunction * (symmetric difference) of the given {@link Collection}s. * <p> * The cardinality of each element <i>e</i> in the returned * {@link Collection} will be equal to * <tt>max(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>)) - min(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>))</tt>. * <p> * This is equivalent to * <tt>{@link #subtract subtract}({@link #union union(a,b)},{@link #intersection intersection(a,b)})</tt> * or * <tt>{@link #union union}({@link #subtract subtract(a,b)},{@link #subtract subtract(b,a)})</tt>. * * @param a * the first collection, must not be null * @param b * the second collection, must not be null * @return the symmetric difference of the two collections */ public static <E> Collection<E> disjunction(final Collection<E> a, final Collection<E> b) { if (a == null || b == null) { return null; } List<E> list = getArrayList(); Map<E, Integer> mapa = getCardinalityMap(a); Map<E, Integer> mapb = getCardinalityMap(b); Set<E> elts = getHashSet(a); elts.addAll(b); for (E e : elts) { for (int i = 0, m = ((Math.max(getFreq(e, mapa), getFreq(e, mapb))) - (Math.min(getFreq(e, mapa), getFreq(e, mapb)))); i < m; i++) { list.add(e); } } return list; } public static <E> ArrayList<E> getArrayList() { return new ArrayList<E>(); } public static <E> ArrayList<E> getArrayList(int initialCapacity) { return new ArrayList<E>(initialCapacity); } public static <E> ArrayList<E> getArrayList(Collection<? extends E> collection) { return new ArrayList<E>(collection); } /** * Returns a {@link Map} mapping each unique element in the given * {@link Collection} to an {@link Integer} representing the number of * occurrences of that element in the {@link Collection}. * <p> * Only those elements present in the collection will appear as keys in the * map. * * @param coll * the collection to get the cardinality map for, must not be * null * @return the populated cardinality map */ public static <E> Map<E, Integer> getCardinalityMap(final Collection<E> coll) { if (coll == null) { return null; } Map<E, Integer> count = getHashMap(); for (E e : coll) { Integer c = count.get(e); if (c == null) { count.put(e, INTEGER_ONE); } else { count.put(e, new Integer(c.intValue() + 1)); } } return count; } public static <E> HashSet<E> getHashSet() { return new HashSet<E>(); } public static <E> HashSet<E> getHashSet(int initialCapacity) { return new HashSet<E>(initialCapacity); } public static <E> HashSet<E> getHashSet(Collection<? extends E> collection) { return new HashSet<E>(collection); } public static <E> HashSet<E> getHashSet(int initialCapacity, float loadFactor) { return new HashSet<E>(initialCapacity, loadFactor); } /** * Adds all elements in the iteration to the given collection. * * @param collection * the collection to add to, must not be null * @param iterator * the iterator of elements to add, must not be null * @throws NullPointerException * if the collection or iterator is null */ public static <E> void addAll(Collection<E> collection, Iterator<E> iterator) { if (collection == null || iterator == null) { return; } while (iterator.hasNext()) { collection.add(iterator.next()); } } /** * Adds all elements in the enumeration to the given collection. * * @param collection * the collection to add to, must not be null * @param enumeration * the enumeration of elements to add, must not be null * @throws NullPointerException * if the collection or enumeration is null */ public static <E> void addAll(Collection<E> collection, Enumeration<E> enumeration) { if (collection == null || enumeration == null) { return; } while (enumeration.hasMoreElements()) { collection.add(enumeration.nextElement()); } } /** * Adds all elements in the array to the given collection. * * @param collection * the collection to add to, must not be null * @param elements * the array of elements to add, must not be null * @throws NullPointerException * if the collection or array is null */ public static <E> void addAll(Collection<E> collection, E[] elements) { if (collection == null || elements == null) { return; } for (E e : elements) { collection.add(e); } } private static final <E> int getFreq(final E obj, final Map<E, Integer> freqMap) { Integer count = freqMap.get(obj); if (count != null) { return count.intValue(); } return 0; } public static <K, V> HashMap<K, V> getHashMap() { return new HashMap<K, V>(); } public static <K, V> HashMap<K, V> getHashMap(int initialCapacity) { return new HashMap<K, V>(initialCapacity); } public static <K, V> HashMap<K, V> getHashMap(Map<? extends K, ? extends V> map) { return new HashMap<K, V>(map); } public static <K, V> HashMap<K, V> getHashMap(int initialCapacity, float loadFactor) { return new HashMap<K, V>(initialCapacity, loadFactor); } /** * Returns the <code>index</code>-th value in <code>object</code>, throwing * <code>IndexOutOfBoundsException</code> if there is no such element or * <code>IllegalArgumentException</code> if <code>object</code> is not an * instance of one of the supported types. * <p> * The supported types, and associated semantics are: * <ul> * <li>Map -- the value returned is the <code>Map.Entry</code> in position * <code>index</code> in the map's <code>entrySet</code> iterator, if there * is such an entry.</li> * <li>List -- this method is equivalent to the list's get method.</li> * <li>Array -- the <code>index</code>-th array entry is returned, if there * is such an entry; otherwise an <code>IndexOutOfBoundsException</code> is * thrown.</li> * <li>Collection -- the value returned is the <code>index</code>-th object * returned by the collection's default iterator, if there is such an * element.</li> * <li>Iterator or Enumeration -- the value returned is the * <code>index</code>-th object in the Iterator/Enumeration, if there is * such an element. The Iterator/Enumeration is advanced to * <code>index</code> (or to the end, if <code>index</code> exceeds the * number of entries) as a side effect of this method.</li> * </ul> * * @param object * the object to get a value from * @param index * the index to get * @return the object at the specified index * @throws IndexOutOfBoundsException * if the index is invalid * @throws IllegalArgumentException * if the object type is invalid */ public static Object get(Object object, int index) { if (index < 0) { throw new IndexOutOfBoundsException("Index cannot be negative: " + index); } if (object instanceof Map) { Map<?, ?> map = (Map<?, ?>) object; Iterator<?> iterator = map.entrySet().iterator(); return get(iterator, index); } else if (object instanceof List) { return ((List<?>) object).get(index); } else if (object instanceof Object[]) { return ((Object[]) object)[index]; } else if (object instanceof Iterator) { Iterator<?> it = (Iterator<?>) object; while (it.hasNext()) { index--; if (index == -1) { return it.next(); } else { it.next(); } } throw new IndexOutOfBoundsException("Entry does not exist: " + index); } else if (object instanceof Collection) { Iterator<?> iterator = ((Collection<?>) object).iterator(); return get(iterator, index); } else if (object instanceof Enumeration) { Enumeration<?> it = (Enumeration<?>) object; while (it.hasMoreElements()) { index--; if (index == -1) { return it.nextElement(); } else { it.nextElement(); } } throw new IndexOutOfBoundsException("Entry does not exist: " + index); } else if (object == null) { throw new IllegalArgumentException("Unsupported object type: null"); } else { try { return Array.get(object, index); } catch (IllegalArgumentException ex) { throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName()); } } } }