]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/collections/CollectionUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils.datastructures / src / org / simantics / utils / datastructures / collections / CollectionUtils.java
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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.utils.datastructures.collections;\r
13 \r
14 import gnu.trove.map.hash.TObjectIntHashMap;\r
15 import gnu.trove.set.hash.THashSet;\r
16 \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
26 \r
27 import org.simantics.utils.datastructures.Pair;\r
28 \r
29 /**\r
30  * @author Tuukka Lehtonen\r
31  */\r
32 public final class CollectionUtils {\r
33 \r
34     /**\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
37      * may be null.\r
38      * \r
39      * @param <T>\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
45      */\r
46     public static <T> boolean checkedAdd(Collection<T> toBeAdded, Collection<T> addTo) {\r
47         assert addTo != null;\r
48         if (toBeAdded == null)\r
49             return false;\r
50         return addTo.addAll(toBeAdded);\r
51     }\r
52 \r
53     /**\r
54      * @return the accumulated size of all the specified collections\r
55      */\r
56     public static int sizeAll(Collection<?>... collections) {\r
57         int size = 0;\r
58         for (Collection<?> c : collections)\r
59             size += c.size();\r
60         return size;\r
61     }\r
62 \r
63     /**\r
64      * @return a new ArrayList<T> that sequentially contains all the elements in\r
65      *         the specified collections\r
66      */\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
71             result.addAll(c);\r
72         return result;\r
73     }\r
74 \r
75     /**\r
76      * @return a new HashSet<T> that contains once all the elements in the\r
77      *         specified collections\r
78      */\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
83             result.addAll(c);\r
84         return result;\r
85     }\r
86 \r
87     /**\r
88      * A specialization of {@link #join(Collection...)} for two arguments.\r
89      */\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
96         return result;\r
97     }\r
98     \r
99     static class PairFirstComparator<K extends Comparable<K>> implements Comparator<Pair<K, ?>> {\r
100 \r
101                 @Override\r
102                 public int compare(Pair<K,?> o1, Pair<K,?> o2) {\r
103                         return o1.first.compareTo(o2.first);\r
104                 }\r
105         \r
106     }\r
107     \r
108     static class PairSecondComparator<V extends Comparable<V>> implements Comparator<Pair<?, V>> {\r
109 \r
110                 @Override\r
111                 public int compare(Pair<?, V> o1, Pair<?, V> o2) {\r
112                         return o1.second.compareTo(o2.second);\r
113                 }\r
114         \r
115      }    \r
116     \r
117     public static <K> Collection<Pair<K,Integer>> valueSortedEntries(TObjectIntHashMap<K> map) {\r
118         \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
122         return result;\r
123         \r
124     }\r
125 \r
126     public static <K, V extends Comparable<V>> List<Pair<K,V>> valueSortedEntries(Map<K,V> map) {\r
127         \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
131         return result;\r
132         \r
133     }\r
134     \r
135     public static <K extends Comparable<K>, V> List<V> sortedBy(List<K> keys, List<V> values) {\r
136 \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
142         return result;\r
143 \r
144     }\r
145 \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
150         return values;\r
151     }\r
152     \r
153     /**\r
154      * A specialization of {@link #join(Set...)} for two arguments.\r
155      */\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
162         return result;\r
163     }\r
164 \r
165     /*\r
166      * Some tests.\r
167      */\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
174 \r
175         Collection<String> c123 = join(c1, c2, c3);\r
176         Collection<String> c12 = join(c1, c2);\r
177 \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
182 \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
186     }\r
187 \r
188     public static <T> void toggle(Set<T> src, Set<T> toggleSet)\r
189     {\r
190         for (T i : toggleSet)\r
191         {\r
192                 if (src.contains(i))\r
193                         src.remove(i);\r
194                 else \r
195                         src.add(i);\r
196         }\r
197     }\r
198 \r
199     public static <T> List<T> toList(@SuppressWarnings("unchecked") T...objs) \r
200     {\r
201         ArrayList<T> result = new ArrayList<T>(objs.length);\r
202         for (T o : objs)\r
203                 result.add(o);\r
204         return result;\r
205     }\r
206 \r
207     public static <T> Set<T> toSet(@SuppressWarnings("unchecked") T...objs)\r
208     {\r
209         THashSet<T> result = new THashSet<T>(objs.length);\r
210         for (T o : objs)\r
211                 result.add(o);\r
212         result.compact();\r
213         return result;\r
214     }\r
215     \r
216     /**\r
217      * Remove elements that appear more than once. Keep order otherwise.\r
218      * @param list to be pruned\r
219      */\r
220     public static void unique(List<?> list) {\r
221         int c = list.size();\r
222         int i = c-1;\r
223         while (i>0) {\r
224                 Object o = list.get(i);\r
225                 int index = list.indexOf(o);\r
226                 if (index>=0) {\r
227                         list.remove(index);\r
228                         c--;\r
229                         i--;\r
230                 } else {\r
231                         i--;\r
232                 }\r
233         }\r
234     }\r
235 \r
236     public static <T> T element(Collection<T> collection, int n) {\r
237         \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
243         return it.next();\r
244         \r
245     }\r
246     \r
247     public static String toString(Collection<?> collection, String separator) {\r
248         StringBuilder sb = new StringBuilder();\r
249         \r
250         int index = 0;\r
251         for (Object o : collection) {\r
252                 if ( index++>0 ) sb.append(separator);\r
253                 sb.append( o.toString() );\r
254         }\r
255         \r
256         return sb.toString();\r
257     }\r
258     \r
259     public static String toString(Object[] array, String separator) {\r
260         StringBuilder sb = new StringBuilder();\r
261         \r
262         int index = 0;\r
263         for (Object o : array) {\r
264                 if ( index++>0 ) sb.append(separator);\r
265                 sb.append( o.toString() );\r
266         }\r
267         \r
268         return sb.toString();\r
269     }\r
270     \r
271 }\r