]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/collections/CollectionUtils.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.utils.datastructures / src / org / simantics / utils / datastructures / collections / CollectionUtils.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.utils.datastructures.collections;
13
14 import gnu.trove.map.hash.TObjectIntHashMap;
15 import gnu.trove.set.hash.THashSet;
16
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.Comparator;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.simantics.utils.datastructures.Pair;
28
29 /**
30  * @author Tuukka Lehtonen
31  */
32 public final class CollectionUtils {
33
34     /**
35      * Add the elements in <code>toBeAdded</code> to addTo. The only difference
36      * to {@link Collection#addAll(Collection)} is that <code>toBeAdded</code>
37      * may be null.
38      * 
39      * @param <T>
40      * @param toBeAdded collection of elements to be added to <code>addTo</code> or
41      *        <code>null</code> to do nothing
42      * @param addTo the collection the elements should be added to
43      * @return <code>true</code> if the destination collection changed as a
44      *         result of the operation
45      */
46     public static <T> boolean checkedAdd(Collection<T> toBeAdded, Collection<T> addTo) {
47         assert addTo != null;
48         if (toBeAdded == null)
49             return false;
50         return addTo.addAll(toBeAdded);
51     }
52
53     /**
54      * @return the accumulated size of all the specified collections
55      */
56     public static int sizeAll(Collection<?>... collections) {
57         int size = 0;
58         for (Collection<?> c : collections)
59             size += c.size();
60         return size;
61     }
62
63     /**
64      * @return a new ArrayList<T> that sequentially contains all the elements in
65      *         the specified collections
66      */
67     public static <T> Collection<T> join(@SuppressWarnings("unchecked") Collection<T>... collections) {
68         int size = sizeAll(collections);
69         ArrayList<T> result = new ArrayList<T>(size);
70         for (Collection<T> c : collections)
71             result.addAll(c);
72         return result;
73     }
74
75     /**
76      * @return a new HashSet<T> that contains once all the elements in the
77      *         specified collections
78      */
79     public static <T> Set<T> join(@SuppressWarnings("unchecked") Set<T>... collections) {
80         int size = sizeAll(collections);
81         HashSet<T> result = new HashSet<T>(size);
82         for (Collection<T> c : collections)
83             result.addAll(c);
84         return result;
85     }
86
87     /**
88      * A specialization of {@link #join(Collection...)} for two arguments.
89      */
90     public static <T> Collection<T> join(Collection<T> first, Collection<T> second) {
91         int size = first.size();
92         size += second.size();
93         ArrayList<T> result = new ArrayList<T>(size);
94         result.addAll(first);
95         result.addAll(second);
96         return result;
97     }
98     
99     static class PairFirstComparator<K extends Comparable<K>> implements Comparator<Pair<K, ?>> {
100
101                 @Override
102                 public int compare(Pair<K,?> o1, Pair<K,?> o2) {
103                         return o1.first.compareTo(o2.first);
104                 }
105         
106     }
107     
108     static class PairSecondComparator<V extends Comparable<V>> implements Comparator<Pair<?, V>> {
109
110                 @Override
111                 public int compare(Pair<?, V> o1, Pair<?, V> o2) {
112                         return o1.second.compareTo(o2.second);
113                 }
114         
115      }    
116     
117     public static <K> Collection<Pair<K,Integer>> valueSortedEntries(TObjectIntHashMap<K> map) {
118         
119         ArrayList<Pair<K,Integer>> result = new ArrayList<Pair<K,Integer>>();
120         for(K key : map.keySet()) result.add(new Pair<K,Integer>(key, map.get(key)));
121         Collections.sort(result, new PairSecondComparator<Integer>());
122         return result;
123         
124     }
125
126     public static <K, V extends Comparable<V>> List<Pair<K,V>> valueSortedEntries(Map<K,V> map) {
127         
128         ArrayList<Pair<K,V>> result = new ArrayList<Pair<K,V>>(); 
129         for(Map.Entry<K, V> entry : map.entrySet()) result.add(new Pair<K,V>(entry.getKey(), entry.getValue()));
130         Collections.sort(result, new PairSecondComparator<V>());
131         return result;
132         
133     }
134     
135     public static <K extends Comparable<K>, V> List<V> sortedBy(List<K> keys, List<V> values) {
136
137         ArrayList<Pair<V,K>> work = new ArrayList<Pair<V,K>>();
138         for(int i=0;i<keys.size();i++) work.add(Pair.make(values.get(i), keys.get(i)));
139         Collections.sort(work, new PairSecondComparator<K>());
140         ArrayList<V> result = new ArrayList<V>();
141         for(Pair<V, K> pair : work) result.add(pair.first);
142         return result;
143
144     }
145
146     public static <K extends Comparable<K>,V> Collection<V> sortByFirst(List<Pair<K,V>> collection) {
147         Collections.sort(collection, new PairFirstComparator<K>());
148         ArrayList<V> values = new ArrayList<V>();
149         for(Pair<K,V> pair : collection) values.add(pair.second);
150         return values;
151     }
152     
153     /**
154      * A specialization of {@link #join(Set...)} for two arguments.
155      */
156     public static <T> Set<T> join(Set<T> first, Set<T> second) {
157         int size = first.size();
158         size += second.size();
159         HashSet<T> result = new HashSet<T>(size);
160         result.addAll(first);
161         result.addAll(second);
162         return result;
163     }
164
165     /*
166      * Some tests.
167      */
168     @SuppressWarnings({ "unused", "unchecked" })
169     public static void main(String[] args) {
170         Collection<String> c1 = Collections.singleton("FOO");
171         Collection<String> c2 = Collections.singleton("BAR");
172         Collection<String> c3 = Collections.singleton("BAZ");
173         Collection<String> c4 = Collections.singleton("FOO");
174
175         Collection<String> c123 = join(c1, c2, c3);
176         Collection<String> c12 = join(c1, c2);
177
178         Set<String> s1 = Collections.singleton("FOO");
179         Set<String> s2 = Collections.singleton("BAR");
180         Set<String> s3 = Collections.singleton("BAZ");
181         Set<String> s4 = Collections.singleton("FOO");
182
183         Set<String> s123 = join(s1, s2, s3);
184         Set<String> s12 = join(s1, s2);
185         Set<String> s14 = join(s1, s4);
186     }
187
188     public static <T> void toggle(Set<T> src, Set<T> toggleSet)
189     {
190         for (T i : toggleSet)
191         {
192                 if (src.contains(i))
193                         src.remove(i);
194                 else 
195                         src.add(i);
196         }
197     }
198
199     public static <T> List<T> toList(@SuppressWarnings("unchecked") T...objs) 
200     {
201         ArrayList<T> result = new ArrayList<T>(objs.length);
202         for (T o : objs)
203                 result.add(o);
204         return result;
205     }
206
207     public static <T> Set<T> toSet(@SuppressWarnings("unchecked") T...objs)
208     {
209         THashSet<T> result = new THashSet<T>(objs.length);
210         for (T o : objs)
211                 result.add(o);
212         result.compact();
213         return result;
214     }
215     
216     /**
217      * Remove elements that appear more than once. Keep order otherwise.
218      * @param list to be pruned
219      */
220     public static void unique(List<?> list) {
221         int c = list.size();
222         int i = c-1;
223         while (i>0) {
224                 Object o = list.get(i);
225                 int index = list.indexOf(o);
226                 if (index>=0) {
227                         list.remove(index);
228                         c--;
229                         i--;
230                 } else {
231                         i--;
232                 }
233         }
234     }
235
236     public static <T> T element(Collection<T> collection, int n) {
237         
238         if (collection instanceof List<?>)
239             return ((List<T>) collection).get(n);
240         if(n >= collection.size()) throw new IllegalArgumentException();
241         Iterator<T> it = collection.iterator();
242         for( int i=0;i<n-1;i++ ) it.next();
243         return it.next();
244         
245     }
246     
247     public static String toString(Collection<?> collection, String separator) {
248         StringBuilder sb = new StringBuilder();
249         
250         int index = 0;
251         for (Object o : collection) {
252                 if ( index++>0 ) sb.append(separator);
253                 sb.append( o.toString() );
254         }
255         
256         return sb.toString();
257     }
258     
259     public static String toString(Object[] array, String separator) {
260         StringBuilder sb = new StringBuilder();
261         
262         int index = 0;
263         for (Object o : array) {
264                 if ( index++>0 ) sb.append(separator);
265                 sb.append( o.toString() );
266         }
267         
268         return sb.toString();
269     }
270     
271 }