PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Java.NET/JavApi Commons collections (Apache Port)/org.apache.commons.collections.CollectionUtils.cs

https://github.com/gadfly/nofs
C# | 1224 lines | 670 code | 46 blank | 508 comment | 175 complexity | e579bcf35bfabc4b6de86539f502d687 MD5 | raw file
  1. /*
  2. * Licensed under the Apache License, Version 2.0 (the "License");
  3. * you may not use this file except in compliance with the License.
  4. * You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. *
  14. */
  15. using System;
  16. using java = biz.ritter.javapi;
  17. using org.apache.commons.collections.collection;
  18. namespace org.apache.commons.collections
  19. {
  20. /**
  21. * Provides utility methods and decorators for {@link Collection} instances.
  22. *
  23. * @since Commons Collections 1.0
  24. * @version $Revision$ $Date$
  25. *
  26. * @author Rodney Waldhoff
  27. * @author Paul Jack
  28. * @author Stephen Colebourne
  29. * @author Steve Downey
  30. * @author Herve Quiroz
  31. * @author Peter KoBek
  32. * @author Matthew Hawthorne
  33. * @author Janek Bogucki
  34. * @author Phil Steitz
  35. * @author Steven Melzer
  36. * @author Jon Schewe
  37. * @author Neil O'Toole
  38. * @author Stephen Smith
  39. */
  40. public class CollectionUtils
  41. {
  42. /** Constant to avoid repeated object creation */
  43. private static java.lang.Integer INTEGER_ONE = new java.lang.Integer(1);
  44. /**
  45. * An empty unmodifiable collection.
  46. * The JDK provides empty Set and List implementations which could be used for
  47. * this purpose. However they could be cast to Set or List which might be
  48. * undesirable. This implementation only implements Collection.
  49. */
  50. public static readonly java.util.Collection<Object> EMPTY_COLLECTION = UnmodifiableCollection.decorate(new java.util.ArrayList<Object>());
  51. /**
  52. * <code>CollectionUtils</code> should not normally be instantiated.
  53. */
  54. public CollectionUtils()
  55. {
  56. }
  57. /**
  58. * Returns a {@link Collection} containing the union
  59. * of the given {@link Collection}s.
  60. * <p>
  61. * The cardinality of each element in the returned {@link Collection}
  62. * will be equal to the maximum of the cardinality of that element
  63. * in the two given {@link Collection}s.
  64. *
  65. * @param a the first collection, must not be null
  66. * @param b the second collection, must not be null
  67. * @return the union of the two collections
  68. * @see Collection#addAll
  69. */
  70. public static java.util.Collection<Object> union(java.util.Collection<Object> a, java.util.Collection<Object> b)
  71. {
  72. java.util.ArrayList<Object> list = new java.util.ArrayList<Object>();
  73. java.util.Map<Object, Object> mapa = getCardinalityMap(a);
  74. java.util.Map<Object, Object> mapb = getCardinalityMap(b);
  75. java.util.Set<Object> elts = new java.util.HashSet<Object>(a);
  76. elts.addAll(b);
  77. java.util.Iterator<Object> it = elts.iterator();
  78. while (it.hasNext())
  79. {
  80. Object obj = it.next();
  81. for (int i = 0, m = java.lang.Math.max(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; i++)
  82. {
  83. list.add(obj);
  84. }
  85. }
  86. return list;
  87. }
  88. /**
  89. * Returns a {@link Collection} containing the intersection
  90. * of the given {@link Collection}s.
  91. * <p>
  92. * The cardinality of each element in the returned {@link Collection}
  93. * will be equal to the minimum of the cardinality of that element
  94. * in the two given {@link Collection}s.
  95. *
  96. * @param a the first collection, must not be null
  97. * @param b the second collection, must not be null
  98. * @return the intersection of the two collections
  99. * @see Collection#retainAll
  100. * @see #containsAny
  101. */
  102. public static java.util.Collection<Object> intersection(java.util.Collection<Object> a, java.util.Collection<Object> b)
  103. {
  104. java.util.ArrayList<Object> list = new java.util.ArrayList<Object>();
  105. java.util.Map<Object, Object> mapa = getCardinalityMap(a);
  106. java.util.Map<Object, Object> mapb = getCardinalityMap(b);
  107. java.util.Set<Object> elts = new java.util.HashSet<Object>(a);
  108. elts.addAll(b);
  109. java.util.Iterator<Object> it = elts.iterator();
  110. while (it.hasNext())
  111. {
  112. Object obj = it.next();
  113. for (int i = 0, m = java.lang.Math.min(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; i++)
  114. {
  115. list.add(obj);
  116. }
  117. }
  118. return list;
  119. }
  120. /**
  121. * Returns a {@link Collection} containing the exclusive disjunction
  122. * (symmetric difference) of the given {@link Collection}s.
  123. * <p>
  124. * The cardinality of each element <i>e</i> in the returned {@link Collection}
  125. * will be equal to
  126. * <tt>max(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>)) - min(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>))</tt>.
  127. * <p>
  128. * This is equivalent to
  129. * <tt>{@link #subtract subtract}({@link #union union(a,b)},{@link #intersection intersection(a,b)})</tt>
  130. * or
  131. * <tt>{@link #union union}({@link #subtract subtract(a,b)},{@link #subtract subtract(b,a)})</tt>.
  132. *
  133. * @param a the first collection, must not be null
  134. * @param b the second collection, must not be null
  135. * @return the symmetric difference of the two collections
  136. */
  137. public static java.util.Collection<Object> disjunction(java.util.Collection<Object> a, java.util.Collection<Object> b)
  138. {
  139. java.util.ArrayList<Object> list = new java.util.ArrayList<Object>();
  140. java.util.Map<Object, Object> mapa = getCardinalityMap(a);
  141. java.util.Map<Object, Object> mapb = getCardinalityMap(b);
  142. java.util.Set<Object> elts = new java.util.HashSet<Object>(a);
  143. elts.addAll(b);
  144. java.util.Iterator<Object> it = elts.iterator();
  145. while (it.hasNext())
  146. {
  147. Object obj = it.next();
  148. for (int i = 0, m = ((java.lang.Math.max(getFreq(obj, mapa), getFreq(obj, mapb))) - (java.lang.Math.min(getFreq(obj, mapa), getFreq(obj, mapb)))); i < m; i++)
  149. {
  150. list.add(obj);
  151. }
  152. }
  153. return list;
  154. }
  155. /**
  156. * Returns a new {@link Collection} containing <tt><i>a</i> - <i>b</i></tt>.
  157. * The cardinality of each element <i>e</i> in the returned {@link Collection}
  158. * will be the cardinality of <i>e</i> in <i>a</i> minus the cardinality
  159. * of <i>e</i> in <i>b</i>, or zero, whichever is greater.
  160. *
  161. * @param a the collection to subtract from, must not be null
  162. * @param b the collection to subtract, must not be null
  163. * @return a new collection with the results
  164. * @see Collection#removeAll
  165. */
  166. public static java.util.Collection<Object> subtract(java.util.Collection<Object> a, java.util.Collection<Object> b)
  167. {
  168. java.util.ArrayList<Object> list = new java.util.ArrayList<Object>(a);
  169. for (java.util.Iterator<Object> it = b.iterator(); it.hasNext(); )
  170. {
  171. list.remove(it.next());
  172. }
  173. return list;
  174. }
  175. /**
  176. * Returns <code>true</code> iff at least one element is in both collections.
  177. * <p>
  178. * In other words, this method returns <code>true</code> iff the
  179. * {@link #intersection} of <i>coll1</i> and <i>coll2</i> is not empty.
  180. *
  181. * @param coll1 the first collection, must not be null
  182. * @param coll2 the first collection, must not be null
  183. * @return <code>true</code> iff the intersection of the collections is non-empty
  184. * @since 2.1
  185. * @see #intersection
  186. */
  187. public static bool containsAny(java.util.Collection<Object> coll1, java.util.Collection<Object> coll2)
  188. {
  189. if (coll1.size() < coll2.size())
  190. {
  191. for (java.util.Iterator<Object> it = coll1.iterator(); it.hasNext(); )
  192. {
  193. if (coll2.contains(it.next()))
  194. {
  195. return true;
  196. }
  197. }
  198. }
  199. else
  200. {
  201. for (java.util.Iterator<Object> it = coll2.iterator(); it.hasNext(); )
  202. {
  203. if (coll1.contains(it.next()))
  204. {
  205. return true;
  206. }
  207. }
  208. }
  209. return false;
  210. }
  211. /**
  212. * Returns a {@link Map} mapping each unique element in the given
  213. * {@link Collection} to an {@link Integer} representing the number
  214. * of occurrences of that element in the {@link Collection}.
  215. * <p>
  216. * Only those elements present in the collection will appear as
  217. * keys in the map.
  218. *
  219. * @param coll the collection to get the cardinality map for, must not be null
  220. * @return the populated cardinality map
  221. */
  222. public static java.util.Map<Object, Object> getCardinalityMap(java.util.Collection<Object> coll)
  223. {
  224. java.util.Map<Object, Object> count = new java.util.HashMap<Object, Object>();
  225. for (java.util.Iterator<Object> it = coll.iterator(); it.hasNext(); )
  226. {
  227. Object obj = it.next();
  228. java.lang.Integer c = (java.lang.Integer)(count.get(obj));
  229. if (c == null)
  230. {
  231. count.put(obj, INTEGER_ONE);
  232. }
  233. else
  234. {
  235. count.put(obj, new java.lang.Integer(c.intValue() + 1));
  236. }
  237. }
  238. return count;
  239. }
  240. /**
  241. * Returns <tt>true</tt> iff <i>a</i> is a sub-collection of <i>b</i>,
  242. * that is, iff the cardinality of <i>e</i> in <i>a</i> is less
  243. * than or equal to the cardinality of <i>e</i> in <i>b</i>,
  244. * for each element <i>e</i> in <i>a</i>.
  245. *
  246. * @param a the first (sub?) collection, must not be null
  247. * @param b the second (super?) collection, must not be null
  248. * @return <code>true</code> iff <i>a</i> is a sub-collection of <i>b</i>
  249. * @see #isProperSubCollection
  250. * @see Collection#containsAll
  251. */
  252. public static bool isSubCollection(java.util.Collection<Object> a, java.util.Collection<Object> b)
  253. {
  254. java.util.Map<Object, Object> mapa = getCardinalityMap(a);
  255. java.util.Map<Object, Object> mapb = getCardinalityMap(b);
  256. java.util.Iterator<Object> it = a.iterator();
  257. while (it.hasNext())
  258. {
  259. Object obj = it.next();
  260. if (getFreq(obj, mapa) > getFreq(obj, mapb))
  261. {
  262. return false;
  263. }
  264. }
  265. return true;
  266. }
  267. /**
  268. * Returns <tt>true</tt> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>,
  269. * that is, iff the cardinality of <i>e</i> in <i>a</i> is less
  270. * than or equal to the cardinality of <i>e</i> in <i>b</i>,
  271. * for each element <i>e</i> in <i>a</i>, and there is at least one
  272. * element <i>f</i> such that the cardinality of <i>f</i> in <i>b</i>
  273. * is strictly greater than the cardinality of <i>f</i> in <i>a</i>.
  274. * <p>
  275. * The implementation assumes
  276. * <ul>
  277. * <li><code>a.size()</code> and <code>b.size()</code> represent the
  278. * total cardinality of <i>a</i> and <i>b</i>, resp. </li>
  279. * <li><code>a.size() < Integer.MAXVALUE</code></li>
  280. * </ul>
  281. *
  282. * @param a the first (sub?) collection, must not be null
  283. * @param b the second (super?) collection, must not be null
  284. * @return <code>true</code> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>
  285. * @see #isSubCollection
  286. * @see Collection#containsAll
  287. */
  288. public static bool isProperSubCollection(java.util.Collection<Object> a, java.util.Collection<Object> b)
  289. {
  290. return (a.size() < b.size()) && CollectionUtils.isSubCollection(a, b);
  291. }
  292. /**
  293. * Returns <tt>true</tt> iff the given {@link Collection}s contain
  294. * exactly the same elements with exactly the same cardinalities.
  295. * <p>
  296. * That is, iff the cardinality of <i>e</i> in <i>a</i> is
  297. * equal to the cardinality of <i>e</i> in <i>b</i>,
  298. * for each element <i>e</i> in <i>a</i> or <i>b</i>.
  299. *
  300. * @param a the first collection, must not be null
  301. * @param b the second collection, must not be null
  302. * @return <code>true</code> iff the collections contain the same elements with the same cardinalities.
  303. */
  304. public static bool isEqualCollection(java.util.Collection<Object> a, java.util.Collection<Object> b)
  305. {
  306. if (a.size() != b.size())
  307. {
  308. return false;
  309. }
  310. else
  311. {
  312. java.util.Map<Object, Object> mapa = getCardinalityMap(a);
  313. java.util.Map<Object, Object> mapb = getCardinalityMap(b);
  314. if (mapa.size() != mapb.size())
  315. {
  316. return false;
  317. }
  318. else
  319. {
  320. java.util.Iterator<Object> it = mapa.keySet().iterator();
  321. while (it.hasNext())
  322. {
  323. Object obj = it.next();
  324. if (getFreq(obj, mapa) != getFreq(obj, mapb))
  325. {
  326. return false;
  327. }
  328. }
  329. return true;
  330. }
  331. }
  332. }
  333. /**
  334. * Returns the number of occurrences of <i>obj</i> in <i>coll</i>.
  335. *
  336. * @param obj the object to find the cardinality of
  337. * @param coll the collection to search
  338. * @return the the number of occurrences of obj in coll
  339. */
  340. public static int cardinality(Object obj, java.util.Collection<Object> coll)
  341. {
  342. if (coll is java.util.Set<Object>)
  343. {
  344. return (coll.contains(obj) ? 1 : 0);
  345. }
  346. if (coll is Bag)
  347. {
  348. return ((Bag)coll).getCount(obj);
  349. }
  350. int count = 0;
  351. if (obj == null)
  352. {
  353. for (java.util.Iterator<Object> it = coll.iterator(); it.hasNext(); )
  354. {
  355. if (it.next() == null)
  356. {
  357. count++;
  358. }
  359. }
  360. }
  361. else
  362. {
  363. for (java.util.Iterator<Object> it = coll.iterator(); it.hasNext(); )
  364. {
  365. if (obj.equals(it.next()))
  366. {
  367. count++;
  368. }
  369. }
  370. }
  371. return count;
  372. }
  373. /**
  374. * Finds the first element in the given collection which matches the given predicate.
  375. * <p>
  376. * If the input collection or predicate is null, or no element of the collection
  377. * matches the predicate, null is returned.
  378. *
  379. * @param collection the collection to search, may be null
  380. * @param predicate the predicate to use, may be null
  381. * @return the first element of the collection which matches the predicate or null if none could be found
  382. */
  383. public static Object find(java.util.Collection<Object> collection, Predicate predicate)
  384. {
  385. if (collection != null && predicate != null)
  386. {
  387. for (java.util.Iterator<Object> iter = collection.iterator(); iter.hasNext(); )
  388. {
  389. Object item = iter.next();
  390. if (predicate.evaluate(item))
  391. {
  392. return item;
  393. }
  394. }
  395. }
  396. return null;
  397. }
  398. /**
  399. * Executes the given closure on each element in the collection.
  400. * <p>
  401. * If the input collection or closure is null, there is no change made.
  402. *
  403. * @param collection the collection to get the input from, may be null
  404. * @param closure the closure to perform, may be null
  405. */
  406. public static void forAllDo(java.util.Collection<Object> collection, Closure closure)
  407. {
  408. if (collection != null && closure != null)
  409. {
  410. for (java.util.Iterator<Object> it = collection.iterator(); it.hasNext(); )
  411. {
  412. closure.execute(it.next());
  413. }
  414. }
  415. }
  416. /**
  417. * Filter the collection by applying a Predicate to each element. If the
  418. * predicate returns false, remove the element.
  419. * <p>
  420. * If the input collection or predicate is null, there is no change made.
  421. *
  422. * @param collection the collection to get the input from, may be null
  423. * @param predicate the predicate to use as a filter, may be null
  424. */
  425. public static void filter(java.util.Collection<Object> collection, Predicate predicate)
  426. {
  427. if (collection != null && predicate != null)
  428. {
  429. for (java.util.Iterator<Object> it = collection.iterator(); it.hasNext(); )
  430. {
  431. if (predicate.evaluate(it.next()) == false)
  432. {
  433. it.remove();
  434. }
  435. }
  436. }
  437. }
  438. /**
  439. * Transform the collection by applying a Transformer to each element.
  440. * <p>
  441. * If the input collection or transformer is null, there is no change made.
  442. * <p>
  443. * This routine is best for Lists, for which set() is used to do the
  444. * transformations "in place." For other Collections, clear() and addAll()
  445. * are used to replace elements.
  446. * <p>
  447. * If the input collection controls its input, such as a Set, and the
  448. * Transformer creates duplicates (or are otherwise invalid), the
  449. * collection may reduce in size due to calling this method.
  450. *
  451. * @param collection the collection to get the input from, may be null
  452. * @param transformer the transformer to perform, may be null
  453. */
  454. public static void transform(java.util.Collection<Object> collection, Transformer transformer)
  455. {
  456. if (collection != null && transformer != null)
  457. {
  458. if (collection is java.util.List<Object>)
  459. {
  460. java.util.List<Object> list = (java.util.List<Object>)collection;
  461. for (java.util.ListIterator<Object> it = list.listIterator(); it.hasNext(); )
  462. {
  463. it.set(transformer.transform(it.next()));
  464. }
  465. }
  466. else
  467. {
  468. java.util.Collection<Object> resultCollection = collect(collection, transformer);
  469. collection.clear();
  470. collection.addAll(resultCollection);
  471. }
  472. }
  473. }
  474. /**
  475. * Counts the number of elements in the input collection that match the predicate.
  476. * <p>
  477. * A <code>null</code> collection or predicate matches no elements.
  478. *
  479. * @param inputCollection the collection to get the input from, may be null
  480. * @param predicate the predicate to use, may be null
  481. * @return the number of matches for the predicate in the collection
  482. */
  483. public static int countMatches(java.util.Collection<Object> inputCollection, Predicate predicate)
  484. {
  485. int count = 0;
  486. if (inputCollection != null && predicate != null)
  487. {
  488. for (java.util.Iterator<Object> it = inputCollection.iterator(); it.hasNext(); )
  489. {
  490. if (predicate.evaluate(it.next()))
  491. {
  492. count++;
  493. }
  494. }
  495. }
  496. return count;
  497. }
  498. /**
  499. * Answers true if a predicate is true for at least one element of a collection.
  500. * <p>
  501. * A <code>null</code> collection or predicate returns false.
  502. *
  503. * @param collection the collection to get the input from, may be null
  504. * @param predicate the predicate to use, may be null
  505. * @return true if at least one element of the collection matches the predicate
  506. */
  507. public static bool exists(java.util.Collection<Object> collection, Predicate predicate)
  508. {
  509. if (collection != null && predicate != null)
  510. {
  511. for (java.util.Iterator<Object> it = collection.iterator(); it.hasNext(); )
  512. {
  513. if (predicate.evaluate(it.next()))
  514. {
  515. return true;
  516. }
  517. }
  518. }
  519. return false;
  520. }
  521. /**
  522. * Selects all elements from input collection which match the given predicate
  523. * into an output collection.
  524. * <p>
  525. * A <code>null</code> predicate matches no elements.
  526. *
  527. * @param inputCollection the collection to get the input from, may not be null
  528. * @param predicate the predicate to use, may be null
  529. * @return the elements matching the predicate (new list)
  530. * @throws NullPointerException if the input collection is null
  531. */
  532. public static java.util.Collection<Object> select(java.util.Collection<Object> inputCollection, Predicate predicate)
  533. {
  534. java.util.ArrayList<Object> answer = new java.util.ArrayList<Object>(inputCollection.size());
  535. select(inputCollection, predicate, answer);
  536. return answer;
  537. }
  538. /**
  539. * Selects all elements from input collection which match the given predicate
  540. * and adds them to outputCollection.
  541. * <p>
  542. * If the input collection or predicate is null, there is no change to the
  543. * output collection.
  544. *
  545. * @param inputCollection the collection to get the input from, may be null
  546. * @param predicate the predicate to use, may be null
  547. * @param outputCollection the collection to output into, may not be null
  548. */
  549. public static void select(java.util.Collection<Object> inputCollection, Predicate predicate, java.util.Collection<Object> outputCollection)
  550. {
  551. if (inputCollection != null && predicate != null)
  552. {
  553. for (java.util.Iterator<Object> iter = inputCollection.iterator(); iter.hasNext(); )
  554. {
  555. Object item = iter.next();
  556. if (predicate.evaluate(item))
  557. {
  558. outputCollection.add(item);
  559. }
  560. }
  561. }
  562. }
  563. /**
  564. * Selects all elements from inputCollection which don't match the given predicate
  565. * into an output collection.
  566. * <p>
  567. * If the input predicate is <code>null</code>, the result is an empty list.
  568. *
  569. * @param inputCollection the collection to get the input from, may not be null
  570. * @param predicate the predicate to use, may be null
  571. * @return the elements <b>not</b> matching the predicate (new list)
  572. * @throws NullPointerException if the input collection is null
  573. */
  574. public static java.util.Collection<Object> selectRejected(java.util.Collection<Object> inputCollection, Predicate predicate)
  575. {
  576. java.util.ArrayList<Object> answer = new java.util.ArrayList<Object>(inputCollection.size());
  577. selectRejected(inputCollection, predicate, answer);
  578. return answer;
  579. }
  580. /**
  581. * Selects all elements from inputCollection which don't match the given predicate
  582. * and adds them to outputCollection.
  583. * <p>
  584. * If the input predicate is <code>null</code>, no elements are added to <code>outputCollection</code>.
  585. *
  586. * @param inputCollection the collection to get the input from, may be null
  587. * @param predicate the predicate to use, may be null
  588. * @param outputCollection the collection to output into, may not be null
  589. */
  590. public static void selectRejected(java.util.Collection<Object> inputCollection, Predicate predicate, java.util.Collection<Object> outputCollection)
  591. {
  592. if (inputCollection != null && predicate != null)
  593. {
  594. for (java.util.Iterator<Object> iter = inputCollection.iterator(); iter.hasNext(); )
  595. {
  596. Object item = iter.next();
  597. if (predicate.evaluate(item) == false)
  598. {
  599. outputCollection.add(item);
  600. }
  601. }
  602. }
  603. }
  604. /**
  605. * Returns a new Collection consisting of the elements of inputCollection transformed
  606. * by the given transformer.
  607. * <p>
  608. * If the input transformer is null, the result is an empty list.
  609. *
  610. * @param inputCollection the collection to get the input from, may not be null
  611. * @param transformer the transformer to use, may be null
  612. * @return the transformed result (new list)
  613. * @throws NullPointerException if the input collection is null
  614. */
  615. public static java.util.Collection<Object> collect(java.util.Collection<Object> inputCollection, Transformer transformer)
  616. {
  617. java.util.ArrayList<Object> answer = new java.util.ArrayList<Object>(inputCollection.size());
  618. collect(inputCollection, transformer, answer);
  619. return answer;
  620. }
  621. /**
  622. * Transforms all elements from the inputIterator with the given transformer
  623. * and adds them to the outputCollection.
  624. * <p>
  625. * If the input iterator or transformer is null, the result is an empty list.
  626. *
  627. * @param inputIterator the iterator to get the input from, may be null
  628. * @param transformer the transformer to use, may be null
  629. * @return the transformed result (new list)
  630. */
  631. public static java.util.Collection<Object> collect(java.util.Iterator<Object> inputIterator, Transformer transformer)
  632. {
  633. java.util.ArrayList<Object> answer = new java.util.ArrayList<Object>();
  634. collect(inputIterator, transformer, answer);
  635. return answer;
  636. }
  637. /**
  638. * Transforms all elements from inputCollection with the given transformer
  639. * and adds them to the outputCollection.
  640. * <p>
  641. * If the input collection or transformer is null, there is no change to the
  642. * output collection.
  643. *
  644. * @param inputCollection the collection to get the input from, may be null
  645. * @param transformer the transformer to use, may be null
  646. * @param outputCollection the collection to output into, may not be null
  647. * @return the outputCollection with the transformed input added
  648. * @throws NullPointerException if the output collection is null
  649. */
  650. public static java.util.Collection<Object> collect(java.util.Collection<Object> inputCollection, Transformer transformer, java.util.Collection<Object> outputCollection)
  651. {
  652. if (inputCollection != null)
  653. {
  654. return collect(inputCollection.iterator(), transformer, outputCollection);
  655. }
  656. return outputCollection;
  657. }
  658. /**
  659. * Transforms all elements from the inputIterator with the given transformer
  660. * and adds them to the outputCollection.
  661. * <p>
  662. * If the input iterator or transformer is null, there is no change to the
  663. * output collection.
  664. *
  665. * @param inputIterator the iterator to get the input from, may be null
  666. * @param transformer the transformer to use, may be null
  667. * @param outputCollection the collection to output into, may not be null
  668. * @return the outputCollection with the transformed input added
  669. * @throws NullPointerException if the output collection is null
  670. */
  671. public static java.util.Collection<Object> collect(java.util.Iterator<Object> inputIterator, Transformer transformer, java.util.Collection<Object> outputCollection)
  672. {
  673. if (inputIterator != null && transformer != null)
  674. {
  675. while (inputIterator.hasNext())
  676. {
  677. Object item = inputIterator.next();
  678. Object value = transformer.transform(item);
  679. outputCollection.add(value);
  680. }
  681. }
  682. return outputCollection;
  683. }
  684. //-----------------------------------------------------------------------
  685. /**
  686. * Adds an element to the collection unless the element is null.
  687. *
  688. * @param collection the collection to add to, must not be null
  689. * @param object the object to add, if null it will not be added
  690. * @return true if the collection changed
  691. * @throws NullPointerException if the collection is null
  692. * @since Commons Collections 3.2
  693. */
  694. public static bool addIgnoreNull(java.util.Collection<Object> collection, Object obj)
  695. {
  696. return (obj == null ? false : collection.add(obj));
  697. }
  698. /**
  699. * Adds all elements in the iteration to the given collection.
  700. *
  701. * @param collection the collection to add to, must not be null
  702. * @param iterator the iterator of elements to add, must not be null
  703. * @throws NullPointerException if the collection or iterator is null
  704. */
  705. public static void addAll(java.util.Collection<Object> collection, java.util.Iterator<Object> iterator)
  706. {
  707. while (iterator.hasNext())
  708. {
  709. collection.add(iterator.next());
  710. }
  711. }
  712. /**
  713. * Adds all elements in the enumeration to the given collection.
  714. *
  715. * @param collection the collection to add to, must not be null
  716. * @param enumeration the enumeration of elements to add, must not be null
  717. * @throws NullPointerException if the collection or enumeration is null
  718. */
  719. public static void addAll(java.util.Collection<Object> collection, java.util.Enumeration<Object> enumeration)
  720. {
  721. while (enumeration.hasMoreElements())
  722. {
  723. collection.add(enumeration.nextElement());
  724. }
  725. }
  726. /**
  727. * Adds all elements in the array to the given collection.
  728. *
  729. * @param collection the collection to add to, must not be null
  730. * @param elements the array of elements to add, must not be null
  731. * @throws NullPointerException if the collection or array is null
  732. */
  733. public static void addAll(java.util.Collection<Object> collection, Object[] elements)
  734. {
  735. for (int i = 0, size = elements.Length; i < size; i++)
  736. {
  737. collection.add(elements[i]);
  738. }
  739. }
  740. /**
  741. * Given an Object, and an index, returns the nth value in the
  742. * object.
  743. * <ul>
  744. * <li>If obj is a Map, returns the nth value from the <b>keySet</b> iterator, unless
  745. * the Map contains an Integer key with integer value = idx, in which case the
  746. * corresponding map entry value is returned. If idx exceeds the number of entries in
  747. * the map, an empty Iterator is returned.
  748. * <li>If obj is a List or an array, returns the nth value, throwing IndexOutOfBoundsException,
  749. * ArrayIndexOutOfBoundsException, resp. if the nth value does not exist.
  750. * <li>If obj is an iterator, enumeration or Collection, returns the nth value from the iterator,
  751. * returning an empty Iterator (resp. Enumeration) if the nth value does not exist.
  752. * <li>Returns the original obj if it is null or not a Collection or Iterator.
  753. * </ul>
  754. *
  755. * @param obj the object to get an index of, may be null
  756. * @param idx the index to get
  757. * @throws IndexOutOfBoundsException
  758. * @throws ArrayIndexOutOfBoundsException
  759. *
  760. * @deprecated use {@link #get(Object, int)} instead. Will be removed in v4.0
  761. */
  762. public static Object index(Object obj, int idx)
  763. {
  764. return index(obj, new java.lang.Integer(idx));
  765. }
  766. /**
  767. * Given an Object, and a key (index), returns the value associated with
  768. * that key in the Object. The following checks are made:
  769. * <ul>
  770. * <li>If obj is a Map, use the index as a key to get a value. If no match continue.
  771. * <li>Check key is an Integer. If not, return the object passed in.
  772. * <li>If obj is a Map, get the nth value from the <b>keySet</b> iterator.
  773. * If the Map has fewer than n entries, return an empty Iterator.
  774. * <li>If obj is a List or an array, get the nth value, throwing IndexOutOfBoundsException,
  775. * ArrayIndexOutOfBoundsException, resp. if the nth value does not exist.
  776. * <li>If obj is an iterator, enumeration or Collection, get the nth value from the iterator,
  777. * returning an empty Iterator (resp. Enumeration) if the nth value does not exist.
  778. * <li>Return the original obj.
  779. * </ul>
  780. *
  781. * @param obj the object to get an index of
  782. * @param index the index to get
  783. * @return the object at the specified index
  784. * @throws IndexOutOfBoundsException
  785. * @throws ArrayIndexOutOfBoundsException
  786. *
  787. * @deprecated use {@link #get(Object, int)} instead. Will be removed in v4.0
  788. */
  789. public static Object index(Object obj, Object indexJ)
  790. {
  791. if (obj is java.util.Map<Object, Object>)
  792. {
  793. java.util.Map<Object, Object> map = (java.util.Map<Object, Object>)obj;
  794. if (map.containsKey(indexJ))
  795. {
  796. return map.get(indexJ);
  797. }
  798. }
  799. int idx = -1;
  800. if (indexJ is java.lang.Integer)
  801. {
  802. idx = ((java.lang.Integer)indexJ).intValue();
  803. }
  804. if (idx < 0)
  805. {
  806. return obj;
  807. }
  808. else if (obj is java.util.Map<Object, Object>)
  809. {
  810. java.util.Map<Object, Object> map = (java.util.Map<Object, Object>)obj;
  811. java.util.Iterator<Object> iterator = map.keySet().iterator();
  812. return index(iterator, idx);
  813. }
  814. else if (obj is java.util.List<Object>)
  815. {
  816. return ((java.util.List<Object>)obj).get(idx);
  817. }
  818. else if (obj is Object[])
  819. {
  820. return ((Object[])obj)[idx];
  821. }
  822. else if (obj is java.util.Enumeration<Object>)
  823. {
  824. java.util.Enumeration<Object> it = (java.util.Enumeration<Object>)obj;
  825. while (it.hasMoreElements())
  826. {
  827. idx--;
  828. if (idx == -1)
  829. {
  830. return it.nextElement();
  831. }
  832. else
  833. {
  834. it.nextElement();
  835. }
  836. }
  837. }
  838. else if (obj is java.util.Iterator<Object>)
  839. {
  840. return index((java.util.Iterator<Object>)obj, idx);
  841. }
  842. else if (obj is java.util.Collection<Object>)
  843. {
  844. java.util.Iterator<Object> iterator = ((java.util.Collection<Object>)obj).iterator();
  845. return index(iterator, idx);
  846. }
  847. return obj;
  848. }
  849. private static Object index(java.util.Iterator<Object> iterator, int idx)
  850. {
  851. while (iterator.hasNext())
  852. {
  853. idx--;
  854. if (idx == -1)
  855. {
  856. return iterator.next();
  857. }
  858. else
  859. {
  860. iterator.next();
  861. }
  862. }
  863. return iterator;
  864. }
  865. /**
  866. * Returns the <code>index</code>-th value in <code>object</code>, throwing
  867. * <code>IndexOutOfBoundsException</code> if there is no such element or
  868. * <code>IllegalArgumentException</code> if <code>object</code> is not an
  869. * instance of one of the supported types.
  870. * <p>
  871. * The supported types, and associated semantics are:
  872. * <ul>
  873. * <li> Map -- the value returned is the <code>Map.Entry</code> in position
  874. * <code>index</code> in the map's <code>entrySet</code> iterator,
  875. * if there is such an entry.</li>
  876. * <li> List -- this method is equivalent to the list's get method.</li>
  877. * <li> Array -- the <code>index</code>-th array entry is returned,
  878. * if there is such an entry; otherwise an <code>IndexOutOfBoundsException</code>
  879. * is thrown.</li>
  880. * <li> Collection -- the value returned is the <code>index</code>-th object
  881. * returned by the collection's default iterator, if there is such an element.</li>
  882. * <li> Iterator or Enumeration -- the value returned is the
  883. * <code>index</code>-th object in the Iterator/Enumeration, if there
  884. * is such an element. The Iterator/Enumeration is advanced to
  885. * <code>index</code> (or to the end, if <code>index</code> exceeds the
  886. * number of entries) as a side effect of this method.</li>
  887. * </ul>
  888. *
  889. * @param object the object to get a value from
  890. * @param index the index to get
  891. * @return the object at the specified index
  892. * @throws IndexOutOfBoundsException if the index is invalid
  893. * @throws IllegalArgumentException if the object type is invalid
  894. */
  895. public static Object get(Object obj, int index)
  896. {
  897. if (index < 0)
  898. {
  899. throw new java.lang.IndexOutOfBoundsException("Index cannot be negative: " + index);
  900. }
  901. if (obj is java.util.Map<Object, Object>)
  902. {
  903. java.util.Map<Object, Object> map = (java.util.Map<Object, Object>)obj;
  904. java.util.Iterator<Object> iterator = (java.util.Iterator<Object>)map.entrySet().iterator();
  905. return get(iterator, index);
  906. }
  907. else if (obj is java.util.List<Object>)
  908. {
  909. return ((java.util.List<Object>)obj).get(index);
  910. }
  911. else if (obj is Object[])
  912. {
  913. return ((Object[])obj)[index];
  914. }
  915. else if (obj is java.util.Iterator<Object>)
  916. {
  917. java.util.Iterator<Object> it = (java.util.Iterator<Object>)obj;
  918. while (it.hasNext())
  919. {
  920. index--;
  921. if (index == -1)
  922. {
  923. return it.next();
  924. }
  925. else
  926. {
  927. it.next();
  928. }
  929. }
  930. throw new java.lang.IndexOutOfBoundsException("Entry does not exist: " + index);
  931. }
  932. else if (obj is java.util.Collection<Object>)
  933. {
  934. java.util.Iterator<Object> iterator = ((java.util.Collection<Object>)obj).iterator();
  935. return get(iterator, index);
  936. }
  937. else if (obj is java.util.Enumeration<Object>)
  938. {
  939. java.util.Enumeration<Object> it = (java.util.Enumeration<Object>)obj;
  940. while (it.hasMoreElements())
  941. {
  942. index--;
  943. if (index == -1)
  944. {
  945. return it.nextElement();
  946. }
  947. else
  948. {
  949. it.nextElement();
  950. }
  951. }
  952. throw new java.lang.IndexOutOfBoundsException("Entry does not exist: " + index);
  953. }
  954. else if (obj == null)
  955. {
  956. throw new java.lang.IllegalArgumentException("Unsupported object type: null");
  957. }
  958. else
  959. {
  960. try
  961. {
  962. return java.lang.reflect.Array.get(obj, index);
  963. }
  964. catch (java.lang.IllegalArgumentException ex)
  965. {
  966. throw new java.lang.IllegalArgumentException("Unsupported object type: " + obj.getClass().getName());
  967. }
  968. }
  969. }
  970. /**
  971. * Gets the size of the collection/iterator specified.
  972. * <p>
  973. * This method can handles objects as follows
  974. * <ul>
  975. * <li>Collection - the collection size
  976. * <li>Map - the map size
  977. * <li>Array - the array size
  978. * <li>Iterator - the number of elements remaining in the iterator
  979. * <li>Enumeration - the number of elements remaining in the enumeration
  980. * </ul>
  981. *
  982. * @param object the object to get the size of
  983. * @return the size of the specified collection
  984. * @throws IllegalArgumentException thrown if object is not recognised or null
  985. * @since Commons Collections 3.1
  986. */
  987. public static int size(Object obj)
  988. {
  989. int total = 0;
  990. if (obj is java.util.Map<Object, Object>)
  991. {
  992. total = ((java.util.Map<Object, Object>)obj).size();
  993. }
  994. else if (obj is java.util.Collection<Object>)
  995. {
  996. total = ((java.util.Collection<Object>)obj).size();
  997. }
  998. else if (obj is Object[])
  999. {
  1000. total = ((Object[])obj).Length;
  1001. }
  1002. else if (obj is java.util.Iterator<Object>)
  1003. {
  1004. java.util.Iterator<Object> it = (java.util.Iterator<Object>)obj;
  1005. while (it.hasNext())
  1006. {
  1007. total++;
  1008. it.next();
  1009. }
  1010. }
  1011. else if (obj is java.util.Enumeration<Object>)
  1012. {
  1013. java.util.Enumeration<Object> it = (java.util.Enumeration<Object>)obj;
  1014. while (it.hasMoreElements())
  1015. {
  1016. total++;
  1017. it.nextElement();
  1018. }
  1019. }
  1020. else if (obj == null)
  1021. {
  1022. throw new java.lang.IllegalArgumentException("Unsupported object type: null");
  1023. }
  1024. else
  1025. {
  1026. try
  1027. {
  1028. total = java.lang.reflect.Array.getLength(obj);
  1029. }
  1030. catch (java.lang.IllegalArgumentException ex)
  1031. {
  1032. throw new java.lang.IllegalArgumentException("Unsupported object type: " + obj.getClass().getName());
  1033. }
  1034. }
  1035. return total;
  1036. }
  1037. /**
  1038. * Checks if the specified collection/array/iterator is empty.
  1039. * <p>
  1040. * This method can handles objects as follows
  1041. * <ul>
  1042. * <li>Collection - via collection isEmpty
  1043. * <li>Map - via map isEmpty
  1044. * <li>Array - using array size
  1045. * <li>Iterator - via hasNext
  1046. * <li>Enumeration - via hasMoreElements
  1047. * </ul>
  1048. * <p>
  1049. * Note: This method is named to avoid clashing with
  1050. * {@link #isEmpty(Collection)}.
  1051. *
  1052. * @param object the object to get the size of, not null
  1053. * @return true if empty
  1054. * @throws IllegalArgumentException thrown if object is not recognised or null
  1055. * @since Commons Collections 3.2
  1056. */
  1057. public static bool sizeIsEmpty(Object obj)
  1058. {
  1059. if (obj is java.util.Collection<Object>)
  1060. {
  1061. return ((java.util.Collection<Object>)obj).isEmpty();
  1062. }
  1063. else if (obj is java.util.Map<Object, Object>)
  1064. {
  1065. return ((java.util.Map<Object, Object>)obj).isEmpty();
  1066. }
  1067. else if (obj is Object[])
  1068. {
  1069. return ((Object[])obj).Length == 0;
  1070. }
  1071. else if (obj is java.util.Iterator<Object>)
  1072. {
  1073. return ((java.util.Iterator<Object>)obj).hasNext() == false;
  1074. }
  1075. else if (obj is java.util.Enumeration<Object>)
  1076. {
  1077. return ((java.util.Enumeration<Object>)obj).hasMoreElements() == false;
  1078. }
  1079. else if (obj == null)
  1080. {
  1081. throw new java.lang.IllegalArgumentException("Unsupported object type: null");
  1082. }
  1083. else
  1084. {
  1085. try
  1086. {
  1087. return java.lang.reflect.Array.getLength(obj) == 0;
  1088. }
  1089. catch (java.lang.IllegalArgumentException ex)
  1090. {
  1091. throw new java.lang.IllegalArgumentException("Unsupported object type: " + obj.getClass().getName());
  1092. }
  1093. }
  1094. }
  1095. //-----------------------------------------------------------------------
  1096. /**
  1097. * Null-safe check if the specified collection is empty.
  1098. * <p>
  1099. * Null returns true.
  1100. *
  1101. * @param coll the collection to check, may be null
  1102. * @return true if empty or null
  1103. * @since Commons Collections 3.2
  1104. */
  1105. public static bool isEmpty(java.util.Collection<Object> coll)
  1106. {
  1107. return (coll == null || coll.isEmpty());
  1108. }
  1109. /**
  1110. * Null-safe check if the specified collection is not empty.
  1111. * <p>
  1112. * Null returns false.
  1113. *
  1114. * @param coll the collection to check, may be null
  1115. * @return true if non-null and non-empty
  1116. * @since Commons Collections 3.2
  1117. */
  1118. public static bool isNotEmpty(java.util.Collection<Object> coll)
  1119. {
  1120. return !CollectionUtils.isEmpty(coll);
  1121. }
  1122. //-----------------------------------------------------------------------
  1123. /**
  1124. * Reverses the order of the given array.
  1125. *
  1126. * @param array the array to reverse
  1127. */
  1128. public static void reverseArray(Object[] array)
  1129. {
  1130. int i = 0;
  1131. int j = array.Length - 1;
  1132. Object tmp;
  1133. while (j > i)
  1134. {
  1135. tmp = array[j];
  1136. array[j] = array[i];
  1137. array[i] = tmp;
  1138. j--;
  1139. i++;
  1140. }
  1141. }
  1142. private static int getFreq(Object obj, java.util.Map<Object, Object> freqMap)
  1143. {
  1144. java.lang.Integer count = (java.lang.Integer)freqMap.get(obj);
  1145. if (count != null)
  1146. {
  1147. return count.intValue();
  1148. }
  1149. return 0;
  1150. }
  1151. /**
  1152. * Returns true if no more elements can be added to the Collection.
  1153. * <p>
  1154. * This method uses the {@link BoundedCollection} interface to determine the
  1155. * full status. If the collection does not implement this interface then
  1156. * false is returned.
  1157. * <p>
  1158. * The collection does not have to implement this interface directly.
  1159. * If the collection has been decorated using the decorators subpackage
  1160. * then these will be removed to access the BoundedCollection.
  1161. *
  1162. * @param coll the collection to check
  1163. * @return true if the BoundedCollection is full
  1164. * @throws NullPointerException if the collection is null
  1165. */
  1166. public static bool isFull(java.util.Collection<Object> coll)
  1167. {
  1168. if (coll == null)
  1169. {
  1170. throw new java.lang.NullPointerException("The collection must not be null");
  1171. }
  1172. if (coll is BoundedCollection)
  1173. {
  1174. return ((BoundedCollection)coll).isFull();
  1175. }
  1176. try
  1177. {
  1178. BoundedCollection bcoll = UnmodifiableBoundedCollection.dec