PageRenderTime 27ms CodeModel.GetById 1ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/gadfly/nofs
C# | 517 lines | 301 code | 38 blank | 178 comment | 41 complexity | 38a09a0e5416aa7b0e51c5808647243d 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 System.Text;
  17. using java = biz.ritter.javapi;
  18. using org.apache.commons.collections.set;
  19. namespace org.apache.commons.collections
  20. {
  21. /**
  22. * A skeletal implementation of the {@link Bag}
  23. * interface to minimize the effort required for target implementations.
  24. * Subclasses need only to call <code>setMap(Map)</code> in their constructor
  25. * (or invoke the Map constructor) specifying a map instance that will be used
  26. * to store the contents of the bag.
  27. * <p>
  28. * The map will be used to map bag elements to a number; the number represents
  29. * the number of occurrences of that element in the bag.
  30. *
  31. * @deprecated Moved to bag subpackage as AbstractMapBag. Due to be removed in v4.0.
  32. * @since Commons Collections 2.0
  33. * @version $Revision$ $Date$
  34. *
  35. * @author Chuck Burdick
  36. * @author Michael A. Smith
  37. * @author Stephen Colebourne
  38. * @author Janek Bogucki
  39. */
  40. [Obsolete]
  41. public abstract class DefaultMapBag : Bag
  42. {
  43. private java.util.Map<Object, Object> _map = null;
  44. private int _total = 0;
  45. private int _mods = 0;
  46. /**
  47. * No-argument constructor.
  48. * Subclasses should invoke <code>setMap(Map)</code> in
  49. * their constructors.
  50. */
  51. public DefaultMapBag()
  52. {
  53. }
  54. /**
  55. * Constructor that assigns the specified Map as the backing store.
  56. * The map must be empty.
  57. *
  58. * @param map the map to assign
  59. */
  60. protected DefaultMapBag(java.util.Map<Object, Object> map)
  61. {
  62. setMap(map);
  63. }
  64. /**
  65. * Adds a new element to the bag by incrementing its count in the
  66. * underlying map.
  67. *
  68. * @param object the object to add
  69. * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
  70. */
  71. public virtual bool add(Object obj)
  72. {
  73. return add(obj, 1);
  74. }
  75. /**
  76. * Adds a new element to the bag by incrementing its count in the map.
  77. *
  78. * @param object the object to search for
  79. * @param nCopies the number of copies to add
  80. * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
  81. */
  82. public virtual bool add(Object obj, int nCopies)
  83. {
  84. _mods++;
  85. if (nCopies > 0)
  86. {
  87. int count = (nCopies + getCount(obj));
  88. _map.put(obj, new java.lang.Integer(count));
  89. _total += nCopies;
  90. return (count == nCopies);
  91. }
  92. else
  93. {
  94. return false;
  95. }
  96. }
  97. /**
  98. * Invokes {@link #add(Object)} for each element in the given collection.
  99. *
  100. * @param coll the collection to add
  101. * @return <code>true</code> if this call changed the bag
  102. */
  103. public virtual bool addAll(java.util.Collection<Object> coll)
  104. {
  105. bool changed = false;
  106. java.util.Iterator<Object> i = coll.iterator();
  107. while (i.hasNext())
  108. {
  109. bool added = add(i.next());
  110. changed = changed || added;
  111. }
  112. return changed;
  113. }
  114. /**
  115. * Clears the bag by clearing the underlying map.
  116. */
  117. public virtual void clear()
  118. {
  119. _mods++;
  120. _map.clear();
  121. _total = 0;
  122. }
  123. /**
  124. * Determines if the bag contains the given element by checking if the
  125. * underlying map contains the element as a key.
  126. *
  127. * @param object the object to search for
  128. * @return true if the bag contains the given element
  129. */
  130. public virtual bool contains(Object obj)
  131. {
  132. return _map.containsKey(obj);
  133. }
  134. /**
  135. * Determines if the bag contains the given elements.
  136. *
  137. * @param coll the collection to check against
  138. * @return <code>true</code> if the Bag contains all the collection
  139. */
  140. public virtual bool containsAll(java.util.Collection<Object> coll)
  141. {
  142. return containsAll(new HashBag(coll));
  143. }
  144. /**
  145. * Returns <code>true</code> if the bag contains all elements in
  146. * the given collection, respecting cardinality.
  147. *
  148. * @param other the bag to check against
  149. * @return <code>true</code> if the Bag contains all the collection
  150. */
  151. public virtual bool containsAll(Bag other)
  152. {
  153. bool result = true;
  154. java.util.Iterator<Object> i = other.uniqueSet().iterator();
  155. while (i.hasNext())
  156. {
  157. Object current = i.next();
  158. bool contains = getCount(current) >= other.getCount(current);
  159. result = result && contains;
  160. }
  161. return result;
  162. }
  163. /**
  164. * Returns true if the given object is not null, has the precise type
  165. * of this bag, and contains the same number of occurrences of all the
  166. * same elements.
  167. *
  168. * @param object the object to test for equality
  169. * @return true if that object equals this bag
  170. */
  171. public override bool Equals(Object obj)
  172. {
  173. if (obj == this)
  174. {
  175. return true;
  176. }
  177. if (obj is Bag == false)
  178. {
  179. return false;
  180. }
  181. Bag other = (Bag)obj;
  182. if (other.size() != size())
  183. {
  184. return false;
  185. }
  186. for (java.util.Iterator<Object> it = _map.keySet().iterator(); it.hasNext(); )
  187. {
  188. Object element = it.next();
  189. if (other.getCount(element) != getCount(element))
  190. {
  191. return false;
  192. }
  193. }
  194. return true;
  195. }
  196. /**
  197. * Returns the hash code of the underlying map.
  198. *
  199. * @return the hash code of the underlying map
  200. */
  201. public override int GetHashCode()
  202. {
  203. return _map.GetHashCode();
  204. }
  205. /**
  206. * Returns true if the underlying map is empty.
  207. *
  208. * @return true if there are no elements in this bag
  209. */
  210. public virtual bool isEmpty()
  211. {
  212. return _map.isEmpty();
  213. }
  214. public virtual java.util.Iterator<Object> iterator()
  215. {
  216. return new BagIterator(this, extractList().iterator());
  217. }
  218. public virtual bool remove(Object obj)
  219. {
  220. return remove(obj, getCount(obj));
  221. }
  222. public virtual bool remove(Object obj, int nCopies)
  223. {
  224. _mods++;
  225. bool result = false;
  226. int count = getCount(obj);
  227. if (nCopies <= 0)
  228. {
  229. result = false;
  230. }
  231. else if (count > nCopies)
  232. {
  233. _map.put(obj, new java.lang.Integer(count - nCopies));
  234. result = true;
  235. _total -= nCopies;
  236. }
  237. else
  238. { // count > 0 && count <= i
  239. // need to remove all
  240. result = (_map.remove(obj) != null);
  241. _total -= count;
  242. }
  243. return result;
  244. }
  245. public virtual bool removeAll(java.util.Collection<Object> coll)
  246. {
  247. bool result = false;
  248. if (coll != null)
  249. {
  250. java.util.Iterator<Object> i = coll.iterator();
  251. while (i.hasNext())
  252. {
  253. bool changed = remove(i.next(), 1);
  254. result = result || changed;
  255. }
  256. }
  257. return result;
  258. }
  259. /**
  260. * Remove any members of the bag that are not in the given
  261. * bag, respecting cardinality.
  262. *
  263. * @param coll the collection to retain
  264. * @return true if this call changed the collection
  265. */
  266. public virtual bool retainAll(java.util.Collection<Object> coll)
  267. {
  268. return retainAll(new HashBag(coll));
  269. }
  270. /**
  271. * Remove any members of the bag that are not in the given
  272. * bag, respecting cardinality.
  273. * @see #retainAll(Collection)
  274. *
  275. * @param other the bag to retain
  276. * @return <code>true</code> if this call changed the collection
  277. */
  278. public virtual bool retainAll(Bag other)
  279. {
  280. bool result = false;
  281. Bag excess = new HashBag();
  282. java.util.Iterator<Object> i = uniqueSet().iterator();
  283. while (i.hasNext())
  284. {
  285. Object current = i.next();
  286. int myCount = getCount(current);
  287. int otherCount = other.getCount(current);
  288. if (1 <= otherCount && otherCount <= myCount)
  289. {
  290. excess.add(current, myCount - otherCount);
  291. }
  292. else
  293. {
  294. excess.add(current, myCount);
  295. }
  296. }
  297. if (!excess.isEmpty())
  298. {
  299. result = removeAll(excess);
  300. }
  301. return result;
  302. }
  303. /**
  304. * Returns an array of all of this bag's elements.
  305. *
  306. * @return an array of all of this bag's elements
  307. */
  308. public virtual Object[] toArray()
  309. {
  310. return extractList().toArray();
  311. }
  312. /**
  313. * Returns an array of all of this bag's elements.
  314. *
  315. * @param array the array to populate
  316. * @return an array of all of this bag's elements
  317. */
  318. public virtual Object[] toArray<Object>(Object[] array)
  319. {
  320. return extractList().toArray(array);
  321. }
  322. /**
  323. * Returns the number of occurrence of the given element in this bag
  324. * by looking up its count in the underlying map.
  325. *
  326. * @param object the object to search for
  327. * @return the number of occurrences of the object, zero if not found
  328. */
  329. public virtual int getCount(Object obj)
  330. {
  331. int result = 0;
  332. java.lang.Integer count = MapUtils.getInteger(_map, obj);
  333. if (count != null)
  334. {
  335. result = count.intValue();
  336. }
  337. return result;
  338. }
  339. /**
  340. * Returns an unmodifiable view of the underlying map's key set.
  341. *
  342. * @return the set of unique elements in this bag
  343. */
  344. public virtual java.util.Set<Object> uniqueSet()
  345. {
  346. return UnmodifiableSet.decorate(_map.keySet());
  347. }
  348. /**
  349. * Returns the number of elements in this bag.
  350. *
  351. * @return the number of elements in this bag
  352. */
  353. public virtual int size()
  354. {
  355. return _total;
  356. }
  357. /**
  358. * Actually walks the bag to make sure the count is correct and
  359. * resets the running total
  360. *
  361. * @return the current total size
  362. */
  363. protected virtual int calcTotalSize()
  364. {
  365. _total = extractList().size();
  366. return _total;
  367. }
  368. /**
  369. * Utility method for implementations to set the map that backs
  370. * this bag. Not intended for interactive use outside of
  371. * subclasses.
  372. */
  373. protected virtual void setMap(java.util.Map<Object, Object> map)
  374. {
  375. if (map == null || map.isEmpty() == false)
  376. {
  377. throw new java.lang.IllegalArgumentException("The map must be non-null and empty");
  378. }
  379. _map = map;
  380. }
  381. /**
  382. * Utility method for implementations to access the map that backs
  383. * this bag. Not intended for interactive use outside of
  384. * subclasses.
  385. */
  386. protected virtual java.util.Map<Object, Object> getMap()
  387. {
  388. return _map;
  389. }
  390. /**
  391. * Create a list for use in iteration, etc.
  392. */
  393. private java.util.List<Object> extractList()
  394. {
  395. java.util.ArrayList<Object> result = new java.util.ArrayList<Object>();
  396. java.util.Iterator<Object> i = uniqueSet().iterator();
  397. while (i.hasNext())
  398. {
  399. Object current = i.next();
  400. for (int index = getCount(current); index > 0; index--)
  401. {
  402. result.add(current);
  403. }
  404. }
  405. return result;
  406. }
  407. /**
  408. * Return number of modifications for iterator.
  409. *
  410. * @return the modification count
  411. */
  412. internal virtual int modCount()
  413. {
  414. return _mods;
  415. }
  416. /**
  417. * Implement a toString() method suitable for debugging.
  418. *
  419. * @return a debugging toString
  420. */
  421. public override String ToString()
  422. {
  423. StringBuilder buf = new StringBuilder();
  424. buf.append("[");
  425. java.util.Iterator<Object> i = uniqueSet().iterator();
  426. while (i.hasNext())
  427. {
  428. Object current = i.next();
  429. int count = getCount(current);
  430. buf.append(count);
  431. buf.append(":");
  432. buf.append(current);
  433. if (i.hasNext())
  434. {
  435. buf.append(",");
  436. }
  437. }
  438. buf.append("]");
  439. return buf.toString();
  440. }
  441. }
  442. internal class BagIterator : java.util.Iterator<Object>
  443. {
  444. private DefaultMapBag _parent = null;
  445. private java.util.Iterator<Object> _support = null;
  446. private Object _current = null;
  447. private int _mods = 0;
  448. public BagIterator(DefaultMapBag parent, java.util.Iterator<Object> support)
  449. {
  450. _parent = parent;
  451. _support = support;
  452. _current = null;
  453. _mods = parent.modCount();
  454. }
  455. public virtual bool hasNext()
  456. {
  457. return _support.hasNext();
  458. }
  459. public virtual Object next()
  460. {
  461. if (_parent.modCount() != _mods)
  462. {
  463. throw new java.util.ConcurrentModificationException();
  464. }
  465. _current = _support.next();
  466. return _current;
  467. }
  468. public virtual void remove()
  469. {
  470. if (_parent.modCount() != _mods)
  471. {
  472. throw new java.util.ConcurrentModificationException();
  473. }
  474. _support.remove();
  475. _parent.remove(_current, 1);
  476. _mods++;
  477. }
  478. }
  479. }