1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.utils.datastructures.collections;
\r
14 import gnu.trove.map.hash.TObjectIntHashMap;
\r
15 import gnu.trove.set.hash.THashSet;
\r
17 import java.util.ArrayList;
\r
18 import java.util.Collection;
\r
19 import java.util.Collections;
\r
20 import java.util.Comparator;
\r
21 import java.util.HashSet;
\r
22 import java.util.Iterator;
\r
23 import java.util.List;
\r
24 import java.util.Map;
\r
25 import java.util.Set;
\r
27 import org.simantics.utils.datastructures.Pair;
\r
30 * @author Tuukka Lehtonen
\r
32 public final class CollectionUtils {
\r
35 * Add the elements in <code>toBeAdded</code> to addTo. The only difference
\r
36 * to {@link Collection#addAll(Collection)} is that <code>toBeAdded</code>
\r
40 * @param toBeAdded collection of elements to be added to <code>addTo</code> or
\r
41 * <code>null</code> to do nothing
\r
42 * @param addTo the collection the elements should be added to
\r
43 * @return <code>true</code> if the destination collection changed as a
\r
44 * result of the operation
\r
46 public static <T> boolean checkedAdd(Collection<T> toBeAdded, Collection<T> addTo) {
\r
47 assert addTo != null;
\r
48 if (toBeAdded == null)
\r
50 return addTo.addAll(toBeAdded);
\r
54 * @return the accumulated size of all the specified collections
\r
56 public static int sizeAll(Collection<?>... collections) {
\r
58 for (Collection<?> c : collections)
\r
64 * @return a new ArrayList<T> that sequentially contains all the elements in
\r
65 * the specified collections
\r
67 public static <T> Collection<T> join(@SuppressWarnings("unchecked") Collection<T>... collections) {
\r
68 int size = sizeAll(collections);
\r
69 ArrayList<T> result = new ArrayList<T>(size);
\r
70 for (Collection<T> c : collections)
\r
76 * @return a new HashSet<T> that contains once all the elements in the
\r
77 * specified collections
\r
79 public static <T> Set<T> join(@SuppressWarnings("unchecked") Set<T>... collections) {
\r
80 int size = sizeAll(collections);
\r
81 HashSet<T> result = new HashSet<T>(size);
\r
82 for (Collection<T> c : collections)
\r
88 * A specialization of {@link #join(Collection...)} for two arguments.
\r
90 public static <T> Collection<T> join(Collection<T> first, Collection<T> second) {
\r
91 int size = first.size();
\r
92 size += second.size();
\r
93 ArrayList<T> result = new ArrayList<T>(size);
\r
94 result.addAll(first);
\r
95 result.addAll(second);
\r
99 static class PairFirstComparator<K extends Comparable<K>> implements Comparator<Pair<K, ?>> {
\r
102 public int compare(Pair<K,?> o1, Pair<K,?> o2) {
\r
103 return o1.first.compareTo(o2.first);
\r
108 static class PairSecondComparator<V extends Comparable<V>> implements Comparator<Pair<?, V>> {
\r
111 public int compare(Pair<?, V> o1, Pair<?, V> o2) {
\r
112 return o1.second.compareTo(o2.second);
\r
117 public static <K> Collection<Pair<K,Integer>> valueSortedEntries(TObjectIntHashMap<K> map) {
\r
119 ArrayList<Pair<K,Integer>> result = new ArrayList<Pair<K,Integer>>();
\r
120 for(K key : map.keySet()) result.add(new Pair<K,Integer>(key, map.get(key)));
\r
121 Collections.sort(result, new PairSecondComparator<Integer>());
\r
126 public static <K, V extends Comparable<V>> List<Pair<K,V>> valueSortedEntries(Map<K,V> map) {
\r
128 ArrayList<Pair<K,V>> result = new ArrayList<Pair<K,V>>();
\r
129 for(Map.Entry<K, V> entry : map.entrySet()) result.add(new Pair<K,V>(entry.getKey(), entry.getValue()));
\r
130 Collections.sort(result, new PairSecondComparator<V>());
\r
135 public static <K extends Comparable<K>, V> List<V> sortedBy(List<K> keys, List<V> values) {
\r
137 ArrayList<Pair<V,K>> work = new ArrayList<Pair<V,K>>();
\r
138 for(int i=0;i<keys.size();i++) work.add(Pair.make(values.get(i), keys.get(i)));
\r
139 Collections.sort(work, new PairSecondComparator<K>());
\r
140 ArrayList<V> result = new ArrayList<V>();
\r
141 for(Pair<V, K> pair : work) result.add(pair.first);
\r
146 public static <K extends Comparable<K>,V> Collection<V> sortByFirst(List<Pair<K,V>> collection) {
\r
147 Collections.sort(collection, new PairFirstComparator<K>());
\r
148 ArrayList<V> values = new ArrayList<V>();
\r
149 for(Pair<K,V> pair : collection) values.add(pair.second);
\r
154 * A specialization of {@link #join(Set...)} for two arguments.
\r
156 public static <T> Set<T> join(Set<T> first, Set<T> second) {
\r
157 int size = first.size();
\r
158 size += second.size();
\r
159 HashSet<T> result = new HashSet<T>(size);
\r
160 result.addAll(first);
\r
161 result.addAll(second);
\r
168 @SuppressWarnings({ "unused", "unchecked" })
\r
169 public static void main(String[] args) {
\r
170 Collection<String> c1 = Collections.singleton("FOO");
\r
171 Collection<String> c2 = Collections.singleton("BAR");
\r
172 Collection<String> c3 = Collections.singleton("BAZ");
\r
173 Collection<String> c4 = Collections.singleton("FOO");
\r
175 Collection<String> c123 = join(c1, c2, c3);
\r
176 Collection<String> c12 = join(c1, c2);
\r
178 Set<String> s1 = Collections.singleton("FOO");
\r
179 Set<String> s2 = Collections.singleton("BAR");
\r
180 Set<String> s3 = Collections.singleton("BAZ");
\r
181 Set<String> s4 = Collections.singleton("FOO");
\r
183 Set<String> s123 = join(s1, s2, s3);
\r
184 Set<String> s12 = join(s1, s2);
\r
185 Set<String> s14 = join(s1, s4);
\r
188 public static <T> void toggle(Set<T> src, Set<T> toggleSet)
\r
190 for (T i : toggleSet)
\r
192 if (src.contains(i))
\r
199 public static <T> List<T> toList(@SuppressWarnings("unchecked") T...objs)
\r
201 ArrayList<T> result = new ArrayList<T>(objs.length);
\r
207 public static <T> Set<T> toSet(@SuppressWarnings("unchecked") T...objs)
\r
209 THashSet<T> result = new THashSet<T>(objs.length);
\r
217 * Remove elements that appear more than once. Keep order otherwise.
\r
218 * @param list to be pruned
\r
220 public static void unique(List<?> list) {
\r
221 int c = list.size();
\r
224 Object o = list.get(i);
\r
225 int index = list.indexOf(o);
\r
227 list.remove(index);
\r
236 public static <T> T element(Collection<T> collection, int n) {
\r
238 if (collection instanceof List<?>)
\r
239 return ((List<T>) collection).get(n);
\r
240 if(n >= collection.size()) throw new IllegalArgumentException();
\r
241 Iterator<T> it = collection.iterator();
\r
242 for( int i=0;i<n-1;i++ ) it.next();
\r
247 public static String toString(Collection<?> collection, String separator) {
\r
248 StringBuilder sb = new StringBuilder();
\r
251 for (Object o : collection) {
\r
252 if ( index++>0 ) sb.append(separator);
\r
253 sb.append( o.toString() );
\r
256 return sb.toString();
\r
259 public static String toString(Object[] array, String separator) {
\r
260 StringBuilder sb = new StringBuilder();
\r
263 for (Object o : array) {
\r
264 if ( index++>0 ) sb.append(separator);
\r
265 sb.append( o.toString() );
\r
268 return sb.toString();
\r