Java tutorial
//package com.java2s; /* * Copyright 2001-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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 collections15 */ public static <E> Collection<E> disjunction(final Collection<E> a, final Collection<E> b) { ArrayList<E> list = new ArrayList<E>(); Map mapa = getCardinalityMap(a); Map mapb = getCardinalityMap(b); Set<E> elts = new HashSet<E>(a); elts.addAll(b); Iterator<E> it = elts.iterator(); while (it.hasNext()) { E obj = it.next(); for (int i = 0, m = ((Math.max(getFreq(obj, mapa), getFreq(obj, mapb))) - (Math.min(getFreq(obj, mapa), getFreq(obj, mapb)))); i < m; i++) { list.add(obj); } } return list; } /** * Returns a {@link Map} mapping each unique element in the given * {@link Iterable} to an {@link Integer} representing the number * of occurrences of that element in the {@link Iterable}. * <p/> * Only those elements present in the Iterable will appear as * keys in the map. * * @param iterable the collection to get the cardinality map for, must not be null * @return the populated cardinality map */ public static <E> Map<E, java.lang.Integer> getCardinalityMap(final Iterable<E> iterable) { Map<E, Integer> count = new HashMap<E, Integer>(); for (Iterator<E> it = iterable.iterator(); it.hasNext();) { E obj = it.next(); Integer c = count.get(obj); if (c == null) { count.put(obj, INTEGER_ONE); } else { count.put(obj, new Integer(c.intValue() + 1)); } } return count; } /** * Adds all elements in the iteration to the given collection. * @deprecated Replaced by {@link Collection#addAll(java.util.Collection<? extends E>)} * * @param collection the collection to add to * @param iterator the iterator of elements to add, may not be null * @throws NullPointerException if the collection or iterator is null */ public static <E> void addAll(Collection<E> collection, Iterator<? extends E> iterator) { while (iterator.hasNext()) { collection.add(iterator.next()); } } /** * Adds all elements in the enumeration to the given collection. * @deprecated Replaced by {@link Collection#addAll(java.util.Collection<? extends E>)} * * @param collection the collection to add to * @param enumeration the enumeration of elements to add, may not be null * @throws NullPointerException if the collection or enumeration is null */ public static <E> void addAll(Collection<E> collection, Enumeration<? extends E> enumeration) { while (enumeration.hasMoreElements()) { collection.add(enumeration.nextElement()); } } /** * Adds all elements in the array to the given collection. * * @param collection the collection to add to, may not be null * @param elements the array of elements to add, may not be null * @throws NullPointerException if the collection or array is null */ public static <E, T extends E> void addAll(Collection<E> collection, T... elements) { for (int i = 0, size = elements.length; i < size; i++) { collection.add(elements[i]); } } private static final int getFreq(final Object obj, final Map freqMap) { Integer count = (Integer) freqMap.get(obj); if (count != null) { return count.intValue(); } return 0; } /** * 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()); } } } }