/* * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI * for visualizing and manipulating spatial features with geometry and attributes. * * Copyright (C) 2003 Vivid Solutions * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * For more information, contact: * * Vivid Solutions * Suite #1A * 2328 Government Street * Victoria BC V8T 5G5 * Canada * * (250)385-6040 * www.vividsolutions.com */ package com.vividsolutions.jump.util; import com.vividsolutions.jts.util.Assert; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; public class CollectionUtil { public CollectionUtil() { } public static Collection concatenate(Collection a, Collection b) { ArrayList result = new ArrayList(); result.addAll(a); result.addAll(b); return result; } public static List list(Object a, Object b) { ArrayList list = new ArrayList(); list.add(a); list.add(b); return list; } /** * Returns a List of Lists: all combinations of the elements of the given List. * @param maxCombinationSize combinations larger than this value are discarded */ public static List combinations(List original, int maxCombinationSize) { return combinations(original, maxCombinationSize, null); } public static Map inverse(Map map) { Map inverse; try { inverse = (Map) map.getClass().newInstance(); } catch (InstantiationException e) { Assert.shouldNeverReachHere(e.toString()); return null; } catch (IllegalAccessException e) { Assert.shouldNeverReachHere(e.toString()); return null; } for (Iterator i = map.keySet().iterator(); i.hasNext();) { Object key = i.next(); Object value = map.get(key); inverse.put(value, key); } return inverse; } /** * Returns a List of Lists: all combinations of the elements of the given List. * @param maxCombinationSize combinations larger than this value are discarded * @param mandatoryItem an item that all returned combinations must contain, * or null to leave unspecified */ public static List combinations(List original, int maxCombinationSize, Object mandatoryItem) { ArrayList combinations = new ArrayList(); //Combinations are given by the bits of each binary number from 1 to 2^N for (int i = 1; i <= ((int) Math.pow(2, original.size()) - 1); i++) { ArrayList combination = new ArrayList(); for (int j = 0; j < original.size(); j++) { if ((i & (int) Math.pow(2, j)) > 0) { combination.add(original.get(j)); } } if (combination.size() > maxCombinationSize) { continue; } if ((mandatoryItem != null) && !combination.contains(mandatoryItem)) { continue; } combinations.add(combination); } return combinations; } /** * Returns a List of Lists: all combinations of the elements of the given List. */ public static List combinations(List original) { return combinations(original, original.size(), null); } public static void removeKeys(Collection keys, Map map) { for (Iterator i = keys.iterator(); i.hasNext();) { Object key = (Object) i.next(); map.remove(key); } } /** * The nth key corresponds to the nth value */ public static List[] keysAndCorrespondingValues(Map map) { ArrayList keys = new ArrayList(map.keySet()); ArrayList values = new ArrayList(); for (Iterator i = keys.iterator(); i.hasNext();) { Object key = i.next(); values.add(map.get(key)); } return new List[] { keys, values }; } public static Collection concatenate(Collection collections) { ArrayList concatenation = new ArrayList(); for (Iterator i = collections.iterator(); i.hasNext();) { Collection collection = (Collection) i.next(); concatenation.addAll(collection); } return concatenation; } public static Object randomElement(List list) { return list.get((int) Math.floor(Math.random() * list.size())); } public static SortedSet reverseSortedSet(int[] ints) { TreeSet sortedSet = new TreeSet(Collections.reverseOrder()); for (int i = 0; i < ints.length; i++) { sortedSet.add(new Integer(ints[i])); } return sortedSet; } public static List reverse(List list) { Collections.reverse(list); return list; } /** * Data is evenly discarded or duplicated to attain the new size */ public static Collection stretch(Collection source, Collection destination, int destinationSize) { Assert.isTrue(destination.isEmpty()); List originalList = source instanceof List ? (List) source : new ArrayList(source); for (int i = 0; i < destinationSize; i++) { destination.add(originalList.get( (int) Math.round( i * originalList.size() / (double) destinationSize))); } return destination; } public static Object ifNotIn(Object o, Collection c, Object alternative) { return c.contains(o) ? o : alternative; } public static void setIfNull(int i, List list, String value) { if (i >= list.size()) { resize(list, i + 1); } if (list.get(i) != null) { return; } list.set(i, value); } public static void resize(List list, int newSize) { if (newSize < list.size()) { list.subList(newSize, list.size()).clear(); } else { list.addAll(Collections.nCopies(newSize - list.size(), null)); } } public static boolean containsReference(Object[] objects, Object o) { return indexOf(o, objects) > -1; } public static int indexOf(Object o, Object[] objects) { for (int i = 0; i < objects.length; i++) { if (objects[i] == o) { return i; } } return -1; } /** * Brute force, for when HashSet and TreeSet won't work (e.g. #hashCode * implementation isn't appropriate). The original Collection is not modified. */ public static Collection removeDuplicates(Collection original) { ArrayList result = new ArrayList(); for (Iterator i = original.iterator(); i.hasNext();) { Object item = i.next(); if (!result.contains(item)) { result.add(item); } } return result; } public static void addIfNotNull(Object item, Collection collection) { if (item != null) { collection.add(item); } } /** * Modifies and returns the collection. */ public static Collection filterByClass(Collection collection, Class c) { for (Iterator i = collection.iterator(); i.hasNext();) { Object item = i.next(); if (!c.isInstance(item)) { i.remove(); } } return collection; } public static Map createMap(Object[] alternatingKeysAndValues) { return createMap(HashMap.class, alternatingKeysAndValues); } public static Map createMap(Class mapClass, Object[] alternatingKeysAndValues) { Map map = null; try { map = (Map) mapClass.newInstance(); } catch (Exception e) { Assert.shouldNeverReachHere(e.toString()); } for (int i = 0; i < alternatingKeysAndValues.length; i += 2) { map.put(alternatingKeysAndValues[i], alternatingKeysAndValues[i + 1]); } return map; } /** * The Smalltalk #collect method. */ public static Collection collect(Collection collection, Block block) { ArrayList result = new ArrayList(); for (Iterator i = collection.iterator(); i.hasNext();) { Object item = i.next(); result.add(block.yield(item)); } return result; } /** * The Smalltalk #select method. */ public static Collection select(Collection collection, Block block) { ArrayList result = new ArrayList(); for (Iterator i = collection.iterator(); i.hasNext();) { Object item = i.next(); if (Boolean.TRUE.equals(block.yield(item))) { result.add(item); } ; } return result; } public static Object get(Class c, Map map) { if (map.keySet().contains(c)) { return map.get(c); } for (Iterator i = map.keySet().iterator(); i.hasNext();) { Class candidateClass = (Class) i.next(); if (candidateClass.isAssignableFrom(c)) { return map.get(candidateClass); } } return null; } }