001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/framework/util/CollectionUtils.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 037 package org.deegree.framework.util; 038 039 import java.util.Collection; 040 import java.util.Iterator; 041 import java.util.LinkedHashMap; 042 import java.util.LinkedList; 043 import java.util.Map; 044 045 /** 046 * <code>CollectionUtils</code> contains some functionality missing in <code>Arrays</code> and <code>Collections</code>. 047 * 048 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> 049 * @author last edited by: $Author: aschmitz $ 050 * 051 * @version $Revision: 20893 $, $Date: 2009-11-19 14:31:51 +0100 (Do, 19 Nov 2009) $ 052 */ 053 public class CollectionUtils { 054 055 /** 056 * @param <T> 057 * @param col 058 * may not contain null values 059 * @param sep 060 * the separating string 061 * @return a comma separated list of #toString values 062 */ 063 public static <T> String collectionToString( Collection<T> col, String sep ) { 064 StringBuilder sb = new StringBuilder( 512 ); 065 066 Iterator<T> iter = col.iterator(); 067 068 while ( iter.hasNext() ) { 069 sb.append( iter.next() ); 070 if ( iter.hasNext() ) { 071 sb.append( sep ); 072 } 073 } 074 075 return sb.toString(); 076 } 077 078 /** 079 * Wraps a for loop and the creation of a new list. 080 * 081 * @param <T> 082 * @param <U> 083 * @param col 084 * @param mapper 085 * @return a list where the mapper has been applied to each element in the map 086 */ 087 public static <T, U> LinkedList<T> map( U[] col, Mapper<T, U> mapper ) { 088 LinkedList<T> list = new LinkedList<T>(); 089 090 for ( U u : col ) { 091 list.add( mapper.apply( u ) ); 092 } 093 094 return list; 095 } 096 097 /** 098 * Wraps a for loop and the creation of a new list. 099 * 100 * @param <T> 101 * @param <U> 102 * @param col 103 * @param mapper 104 * @return a list where the mapper has been applied to each element in the map 105 */ 106 public static <T, U> LinkedList<T> map( Collection<U> col, Mapper<T, U> mapper ) { 107 LinkedList<T> list = new LinkedList<T>(); 108 109 for ( U u : col ) { 110 list.add( mapper.apply( u ) ); 111 } 112 113 return list; 114 } 115 116 /** 117 * @param <T> 118 * @param array 119 * @param obj 120 * @return true, if the object is contained within the array 121 */ 122 public static <T> boolean contains( T[] array, T obj ) { 123 for ( T t : array ) { 124 if ( obj == t ) { 125 return true; 126 } 127 } 128 129 return false; 130 } 131 132 /** 133 * @param <T> 134 * @param col 135 * @param obj 136 * @return true, if the object is contained within the collection 137 */ 138 public static <T> boolean contains( Collection<T> col, T obj ) { 139 for ( T t : col ) { 140 if ( obj == t ) { 141 return true; 142 } 143 } 144 145 return false; 146 } 147 148 /** 149 * @param <T> 150 * @param col 151 * @param obj 152 * @return true, if an equal object is contained 153 */ 154 public static <T> boolean containsEqual( Collection<T> col, T obj ) { 155 for ( T t : col ) { 156 if ( obj.equals( t ) ) { 157 return true; 158 } 159 } 160 161 return false; 162 } 163 164 /** 165 * Attention: runs in n*n 166 * 167 * @param <T> 168 * @param col 169 * @param other 170 * @return true, if all elements in col have an equal in other 171 */ 172 public static <T> boolean containsAllEqual( Collection<T> col, Collection<T> other ) { 173 for ( T t : col ) { 174 boolean contains = false; 175 inner: for ( T u : other ) { 176 if ( t.equals( u ) ) { 177 contains = true; 178 break inner; 179 } 180 } 181 if ( !contains ) { 182 return false; 183 } 184 } 185 return true; 186 } 187 188 /** 189 * @param <T> 190 * @param array 191 * @param pred 192 * @return the first object for which the predicate is true, or null 193 */ 194 public static <T> T find( T[] array, Predicate<T> pred ) { 195 for ( T t : array ) { 196 if ( pred.eval( t ) ) { 197 return t; 198 } 199 } 200 201 return null; 202 } 203 204 /** 205 * @param <T> 206 * @param col 207 * @param pred 208 * @return the first object for which the predicate is true, or null 209 */ 210 public static <T> T find( Collection<T> col, Predicate<T> pred ) { 211 for ( T t : col ) { 212 if ( pred.eval( t ) ) { 213 return t; 214 } 215 } 216 217 return null; 218 } 219 220 /** 221 * @param <T> 222 * @param col 223 * @param pred 224 * @return only those T, for which the pred is true 225 */ 226 public static <T> LinkedList<T> filter( Collection<T> col, Predicate<T> pred ) { 227 228 LinkedList<T> list = new LinkedList<T>(); 229 for ( T t : col ) { 230 if ( pred.eval( t ) ) { 231 list.add( t ); 232 } 233 } 234 235 return list; 236 } 237 238 /** 239 * @param <T> 240 * @param identity 241 * @param col 242 * @param folder 243 * @return the folded value 244 */ 245 public static <T> T fold( T identity, Collection<T> col, Folder<T> folder ) { 246 if ( col.isEmpty() ) { 247 return identity; 248 } 249 250 Iterator<T> i = col.iterator(); 251 252 T acc = i.next(); 253 254 while ( i.hasNext() ) { 255 acc = folder.fold( acc, i.next() ); 256 } 257 258 return acc; 259 } 260 261 /** 262 * <code>Predicate</code> defines a boolean predicate function interface. 263 * 264 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> 265 * @author last edited by: $Author: aschmitz $ 266 * 267 * @version $Revision: 20893 $, $Date: 2009-11-19 14:31:51 +0100 (Do, 19 Nov 2009) $ 268 * @param <T> 269 * the type of the predicate function's argument 270 */ 271 public static interface Predicate<T> { 272 /** 273 * @param t 274 * @return true, if the predicate is satisfied 275 */ 276 public boolean eval( T t ); 277 } 278 279 /** 280 * <code>Mapper</code> gives a name to a simple function. 281 * 282 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> 283 * @author last edited by: $Author: aschmitz $ 284 * 285 * @version $Revision: 20893 $, $Date: 2009-11-19 14:31:51 +0100 (Do, 19 Nov 2009) $ 286 * @param <T> 287 * the return type of the function 288 * @param <U> 289 * the argument type of the function 290 */ 291 public static interface Mapper<T, U> { 292 /** 293 * @param u 294 * @return an implementation defined value 295 */ 296 public T apply( U u ); 297 } 298 299 /** 300 * <code>Folder</code> 301 * 302 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> 303 * @author last edited by: $Author: aschmitz $ 304 * 305 * @version $Revision: 20893 $, $Date: 2009-11-19 14:31:51 +0100 (Do, 19 Nov 2009) $ 306 * @param <T> 307 */ 308 public static interface Folder<T> { 309 /** 310 * @param t1 311 * @param t2 312 * @return the folded value 313 */ 314 public T fold( T t1, T t2 ); 315 } 316 317 /** 318 * 319 */ 320 public static final Mapper<String, Object> TOSTRINGS = new Mapper<String, Object>() { 321 public String apply( Object u ) { 322 return u.toString(); 323 } 324 }; 325 326 /** 327 * @param vals 328 * @return the array as list 329 */ 330 public static LinkedList<Integer> asList( int[] vals ) { 331 LinkedList<Integer> list = new LinkedList<Integer>(); 332 for ( int i : vals ) { 333 list.add( i ); 334 } 335 return list; 336 } 337 338 /** 339 * Not quite zip... 340 * 341 * @param <T> 342 * @param <U> 343 * @param col 344 * @return a map with the first pair components mapping to the second 345 */ 346 public static <T, U> LinkedHashMap<T, U> unzip( Collection<Pair<T, U>> col ) { 347 LinkedHashMap<T, U> map = new LinkedHashMap<T, U>( col.size() ); 348 for ( Pair<T, U> pair : col ) { 349 map.put( pair.first, pair.second ); 350 } 351 return map; 352 } 353 354 /** 355 * Not quite unzip... 356 * 357 * @param <T> 358 * @param <U> 359 * @param map 360 * @return a list with the keys paired with their values 361 */ 362 public static <T, U> LinkedList<Pair<T, U>> zip( Map<T, U> map ) { 363 LinkedList<Pair<T, U>> list = new LinkedList<Pair<T, U>>(); 364 for ( T key : map.keySet() ) { 365 list.add( new Pair<T, U>( key, map.get( key ) ) ); 366 } 367 return list; 368 } 369 370 /** 371 * @param <T> 372 * @param ts 373 * @return the last element or null 374 */ 375 public static <T> T last( T[] ts ) { 376 return ts == null || ts.length == 0 ? null : ts[ts.length - 1]; 377 } 378 379 }