View Javadoc

1   package cz.cuni.amis.utils.collections;
2   
3   import java.util.ArrayList;
4   import java.util.Arrays;
5   import java.util.Collection;
6   import java.util.Iterator;
7   import java.util.List;
8   import java.util.Random;
9   import java.util.Set;
10  
11  import cz.cuni.amis.utils.IFilter;
12  import cz.cuni.amis.utils.ObjectFilter;
13  
14  public class MyCollections {
15  	
16  	private static Random random = new Random(System.currentTimeMillis());
17  	
18  	/**
19  	 * Returns new list that contains only objects from 'col' that are {@link IFilter#isAccepted(Object)}.
20  	 * @param <T>
21  	 * @param col
22  	 * @param filter
23  	 * @return
24  	 */
25  	public static <T> List<T> getFiltered(Collection<T> col, IFilter filter) {
26  		if (col == null) return null;
27  		if (filter == null) return new ArrayList<T>(col);
28  		ArrayList<T> result = new ArrayList<T>(col.size());
29  		for (T obj : col) {
30  			if (filter.isAccepted(obj)) result.add(obj);
31  		}
32  		return result;
33  	}
34  	
35  	/**
36  	 * Returns new array that contains only objects from 'array' that are {@link IFilter#isAccepted(Object)}.
37  	 * @param <T>
38  	 * @param col
39  	 * @param filter
40  	 * @return
41  	 */
42  	public static <T> T[] getFiltered(T[] array, IFilter filter) {
43  		if (array == null) return null;
44  		if (filter == null) return Arrays.copyOf(array, array.length);		
45  		ArrayList<T> result = new ArrayList<T>(array.length);
46  		for (T obj : array) {
47  			if (filter.isAccepted(obj)) result.add(obj);
48  		}
49  		return (T[]) result.toArray(new Object[0]);
50  	}
51  	
52  	/**
53  	 * Returns random element from the collection.
54  	 * <p><p>
55  	 * <b>WARNING:</b> O(n) time complexity in the worst case scenario!
56  	 * 
57  	 * @param <T>
58  	 * @param col
59  	 * @return
60  	 */
61  	public static <T> T getRandom(Collection<T> col) {
62  		if (col == null) return null;
63  		if (col instanceof List) return getRandom((List<T>)col);
64  		if (col.size() == 0) return null;
65  		int rnd = random.nextInt(col.size());
66  		Iterator<T> iter = col.iterator();
67  		for (int i = 0; i < rnd-1; ++i) iter.next();
68  		return iter.next();
69  	}
70  	
71  	/**
72  	 * Returns random element from the list.
73  	 * <p><p>
74  	 * O(1) time complexity.
75  	 * @param <T>
76  	 * @param list
77  	 * @return
78  	 */
79  	public static <T> T getRandom(List<T> list) {
80  		if (list == null) return null;
81  		if (list.size() == 0) return null;
82  		return list.get(random.nextInt(list.size()));
83  	}
84  	
85  	/**
86  	 * Returns random element from the array.
87  	 * @param <T>
88  	 * @param array
89  	 * @return
90  	 */
91  	public static <T> T getRandom(T[] array) {
92  		if (array == null) return null;
93  		if (array.length == 0) return null;
94  		return array[random.nextInt(array.length)];
95  	}
96  	
97  	/**
98  	 * Returns random element from the collection that is {@link IFilter#isAccepted(Object)} by the 'filter'.
99  	 * <p><p>
100 	 * <b>WARNING:</b> O(n) time complexity in the worst case scenario!
101 	 * 
102 	 * @param <T>
103 	 * @param col
104 	 * @param filter if null, performs {@link MyCollections#getRandom(Collection)}
105 	 * @return
106 	 */
107 	public static <T> T getRandomFiltered(Collection<T> col, IFilter filter) {
108 		if (col == null) return null;
109 		if (filter == null) return getRandom(col);
110 		List<T> filtered = getFiltered(col, filter);
111 		return getRandom(filtered);
112 	}
113 	
114 	/**
115 	 * Returns random element from the array that is {@link IFilter#isAccepted(Object)} by the 'filter'.
116 	 * @param <T>
117 	 * @param array
118 	 * @return
119 	 */
120 	public static <T> T getRandomFiltered(T[] array, IFilter filter) {
121 		if (array == null) return null;
122 		if (filter == null) return getRandom(array);
123 		T[] filtered = getFiltered(array, filter);
124 		return getRandom(filtered);
125 	}
126 	
127 	/**
128 	 * Adds 'objects' to 'list'.
129 	 * @param <T>
130 	 * @param objects
131 	 * @param list
132 	 */
133 	public static <T> void toList(T[] objects, List<T> list) {
134 		if (objects == null) return;
135 		if (list == null) return;
136 		for (T obj : objects) {
137 			list.add(obj);
138 		}
139 	}
140 	
141 	/**
142 	 * Adds 'objects' that satisfies 'filter' to 'list'.
143 	 * @param <T>
144 	 * @param objects
145 	 * @param list
146 	 * @param filter
147 	 */
148 	public static <T> void toList(T[] objects, List<T> list, ObjectFilter filter) {
149 		if (filter == null) {
150 			toList(objects, list);
151 			return;
152 		}
153 		if (objects == null) return;
154 		if (list == null) return;		
155 		for (T obj : objects) {			
156 			if (filter.accept(obj)) {
157 				list.add(obj);
158 			}
159 		}
160 	}
161 	
162 	/**
163 	 * Adds 'objects' that satisfies 'filter' to 'list'.
164 	 * @param <T>
165 	 * @param objects
166 	 * @param list
167 	 * @param filter
168 	 */
169 	public static <T> void toList(T[] objects, List<T> list, IFilter filter) {
170 		if (filter == null) {
171 			toList(objects, list);
172 			return;
173 		}
174 		if (objects == null) return;
175 		if (list == null) return;		
176 		for (T obj : objects) {			
177 			if (filter.isAccepted(obj)) {
178 				list.add(obj);
179 			}
180 		}
181 	}
182 	
183 	public static <T> List<T> asList(T[] objects) {
184 		if (objects == null) return null;
185 		List<T> list = new ArrayList<T>(objects.length);
186 		for (T object : objects) {
187 			list.add(object);
188 		}
189 		return list;
190 	}
191 	
192 	public static <T> List<T> asList(Collection<T> objects) {
193 		if (objects == null) return null;
194 		List<T> list = new ArrayList<T>(objects.size());
195 		for (T object : objects) {
196 			list.add(object);
197 		}
198 		return list;
199 	}
200 	
201 	public static <T> List<T> asList(T[] objects, ObjectFilter filter) {
202 		if (filter == null) return asList(objects);
203 		if (objects == null) return null;
204 		List<T> list = new ArrayList<T>(objects.length);
205 		for (T object : objects) {
206 			if (filter.accept(object)) {
207 				list.add(object);
208 			}
209 		}
210 		return list;
211 	}
212 	
213 	public static <T> List<T> asList(Collection<T> objects, ObjectFilter filter) {
214 		if (filter == null) return asList(objects);
215 		if (objects == null) return null;
216 		List<T> list = new ArrayList<T>(objects.size());
217 		for (T object : objects) {
218 			if (filter.accept(object)) {
219 				list.add(object);
220 			}
221 		}
222 		return list;
223 	}
224 	
225 	public static <T> List<T> asList(T[] objects, IFilter filter) {
226 		if (filter == null) return asList(objects);
227 		if (objects == null) return null;
228 		List<T> list = new ArrayList<T>(objects.length);
229 		for (T object : objects) {
230 			if (filter.isAccepted(object)) {
231 				list.add(object);
232 			}
233 		}
234 		return list;
235 	}
236 	
237 	public static <T> List<T> asList(Collection<T> objects, IFilter filter) {
238 		if (filter == null) return asList(objects);
239 		if (objects == null) return null;
240 		List<T> list = new ArrayList<T>(objects.size());
241 		for (T object : objects) {
242 			if (filter.isAccepted(object)) {
243 				list.add(object);
244 			}
245 		}
246 		return list;
247 	}
248 	
249 	public static String toString(Object objToString, String[] prefixes, String[] postfixes, String[] separators, IToString toString) {
250 		
251 		StringBuffer sb = new StringBuffer(200);
252 		
253 		String[] newPrefixes = null;
254 		String[] newPostfixes = null;
255 		String[] newSeparators = null;
256 		
257 		boolean first = true;
258 		
259 		sb.append(prefixes != null && prefixes.length > 0 ? prefixes[0] : "");
260 		
261 		String separator = separators != null && separators.length > 0 ? separators[0] : "";
262 		
263 		if (objToString.getClass().isArray()) {
264 			objToString = asList((Object[])objToString);
265 		}
266 		if (objToString instanceof Collection) {
267 		
268 			for (Object obj : (Collection)objToString) {
269 				
270 				if (first) first = false;
271 				else sb.append(separator);
272 					
273 				if (obj instanceof Collection) {
274 					if (newPrefixes == null) {
275 						if (prefixes != null && prefixes.length > 1) {
276 							newPrefixes = new String[prefixes.length-1];
277 							System.arraycopy(prefixes, 1, newPrefixes, 0, prefixes.length-1);
278 						} else {
279 							newPrefixes = new String[0];
280 						}
281 						if (postfixes != null && postfixes.length > 1) {
282 							newPostfixes = new String[postfixes.length-1];
283 							System.arraycopy(postfixes, 1, newPostfixes, 0, postfixes.length-1);
284 						} else {
285 							newPostfixes = new String[0];
286 						}
287 						if (separators != null && separators.length > 1) {
288 							newSeparators = new String[separators.length-1];
289 							System.arraycopy(separators, 1, newSeparators, 0, separators.length-1);
290 						} else {
291 							newSeparators = new String[0];
292 						}
293 					}
294 					sb.append(MyCollections.toString(obj, newPrefixes, newPostfixes, newSeparators, toString));
295 				} else {
296 					sb.append(toString.toString(obj));
297 				}
298 			}
299 		} else {
300 			sb.append(toString.toString(objToString));
301 		}
302 			
303 		sb.append(postfixes != null && postfixes.length > 0 ? postfixes[0] : "");
304 		
305 		return sb.toString();
306 	}
307 
308 	public static String toString(Object obj, String prefix, String postfix, String separator) {
309 		return toString(obj, new String[]{prefix}, new String[]{postfix}, new String[]{separator}, TO_STRING );
310 	}
311 	
312 	public static String toString(Object obj, String prefix, String postfix, String separator, IToString toString) {
313 		return toString(obj, new String[]{prefix}, new String[]{postfix}, new String[]{separator}, toString );
314 	}
315 	
316 	public static final IToString TO_STRING = new IToString() {
317 
318 		@Override
319 		public String toString(Object obj) {
320 			return obj.toString();
321 		}
322 		
323 	};
324 	
325 	public static interface IToString {
326 		
327 		public String toString(Object obj);
328 		
329 	}
330 
331 	/**
332 	 * Moves data from 'array' to 'col'.
333 	 * 
334 	 * NPE shielded.
335 	 * 
336 	 * @param array
337 	 * @param col
338 	 */
339 	public static <T> void toCollection(T[] array, Collection<T> col) {
340 		if (array == null) return;
341 		if (col == null) return;
342 		for (T t : array) {
343 			col.add(t);
344 		}
345 	}
346 
347 }