PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://github.com/gadfly/nofs
C# | 378 lines | 196 code | 42 blank | 140 comment | 16 complexity | 1d862fc7c35110be51fdfe7e74ee5c36 MD5 | raw file
Possible License(s): Apache-2.0
  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.iterators;
  18. using org.apache.commons.collections.set;
  19. namespace org.apache.commons.collections.list
  20. {
  21. /**
  22. * Decorates a <code>List</code> to ensure that no duplicates are present
  23. * much like a <code>Set</code>.
  24. * <p>
  25. * The <code>List</code> interface makes certain assumptions/requirements.
  26. * This implementation breaks these in certain ways, but this is merely the
  27. * result of rejecting duplicates.
  28. * Each violation is explained in the method, but it should not affect you.
  29. * Bear in mind that Sets require immutable objects to function correctly.
  30. * <p>
  31. * The {@link org.apache.commons.collections.set.ListOrderedSet ListOrderedSet}
  32. * class provides an alternative approach, by wrapping an existing Set and
  33. * retaining insertion order in the iterator.
  34. * <p>
  35. * This class is java.io.Serializable from Commons Collections 3.1.
  36. *
  37. * @since Commons Collections 3.0
  38. * @version $Revision$ $Date$
  39. *
  40. * @author Matthew Hawthorne
  41. * @author Stephen Colebourne
  42. * @author Tom Dunham
  43. */
  44. [Serializable]
  45. public class SetUniqueList : AbstractSerializableListDecorator
  46. {
  47. /** Serialization version */
  48. private static readonly long serialVersionUID = 7196982186153478694L;
  49. /**
  50. * Internal Set to maintain uniqueness.
  51. */
  52. protected readonly java.util.Set<Object> setJ;
  53. /**
  54. * Factory method to create a SetList using the supplied list to retain order.
  55. * <p>
  56. * If the list contains duplicates, these are removed (first indexed one kept).
  57. * A <code>HashSet</code> is used for the set behaviour.
  58. *
  59. * @param list the list to decorate, must not be null
  60. * @throws IllegalArgumentException if list is null
  61. */
  62. public static SetUniqueList decorate(java.util.List<Object> list)
  63. {
  64. if (list == null)
  65. {
  66. throw new java.lang.IllegalArgumentException("List must not be null");
  67. }
  68. if (list.isEmpty())
  69. {
  70. return new SetUniqueList(list, new java.util.HashSet<Object>());
  71. }
  72. else
  73. {
  74. java.util.List<Object> temp = new java.util.ArrayList<Object>(list);
  75. list.clear();
  76. SetUniqueList sl = new SetUniqueList(list, new java.util.HashSet<Object>());
  77. sl.addAll(temp);
  78. return sl;
  79. }
  80. }
  81. //-----------------------------------------------------------------------
  82. /**
  83. * Constructor that wraps (not copies) the List and specifies the set to use.
  84. * <p>
  85. * The set and list must both be correctly initialised to the same elements.
  86. *
  87. * @param set the set to decorate, must not be null
  88. * @param list the list to decorate, must not be null
  89. * @throws IllegalArgumentException if set or list is null
  90. */
  91. protected internal SetUniqueList(java.util.List<Object> list, java.util.Set<Object> set)
  92. : base(list)
  93. {
  94. if (set == null)
  95. {
  96. throw new java.lang.IllegalArgumentException("Set must not be null");
  97. }
  98. this.setJ = set;
  99. }
  100. //-----------------------------------------------------------------------
  101. /**
  102. * Gets an unmodifiable view as a Set.
  103. *
  104. * @return an unmodifiable set view
  105. */
  106. public virtual java.util.Set<Object> asSet()
  107. {
  108. return UnmodifiableSet.decorate(setJ);
  109. }
  110. //-----------------------------------------------------------------------
  111. /**
  112. * Adds an element to the list if it is not already present.
  113. * <p>
  114. * <i>(Violation)</i>
  115. * The <code>List</code> interface requires that this method returns
  116. * <code>true</code> always. However this class may return <code>false</code>
  117. * because of the <code>Set</code> behaviour.
  118. *
  119. * @param object the object to add
  120. * @return true if object was added
  121. */
  122. public override bool add(Object obj)
  123. {
  124. // gets initial size
  125. int sizeBefore = size();
  126. // adds element if unique
  127. add(size(), obj);
  128. // compares sizes to detect if collection changed
  129. return (sizeBefore != size());
  130. }
  131. /**
  132. * Adds an element to a specific index in the list if it is not already present.
  133. * <p>
  134. * <i>(Violation)</i>
  135. * The <code>List</code> interface makes the assumption that the element is
  136. * always inserted. This may not happen with this implementation.
  137. *
  138. * @param index the index to insert at
  139. * @param object the object to add
  140. */
  141. public override void add(int index, Object obj)
  142. {
  143. // adds element if it is not contained already
  144. if (setJ.contains(obj) == false)
  145. {
  146. base.add(index, obj);
  147. setJ.add(obj);
  148. }
  149. }
  150. /**
  151. * Adds an element to the end of the list if it is not already present.
  152. * <p>
  153. * <i>(Violation)</i>
  154. * The <code>List</code> interface makes the assumption that the element is
  155. * always inserted. This may not happen with this implementation.
  156. *
  157. * @param coll the collection to add
  158. */
  159. public override bool addAll(java.util.Collection<Object> coll)
  160. {
  161. return addAll(size(), coll);
  162. }
  163. /**
  164. * Adds a collection of objects to the end of the list avoiding duplicates.
  165. * <p>
  166. * Only elements that are not already in this list will be added, and
  167. * duplicates from the specified collection will be ignored.
  168. * <p>
  169. * <i>(Violation)</i>
  170. * The <code>List</code> interface makes the assumption that the elements
  171. * are always inserted. This may not happen with this implementation.
  172. *
  173. * @param index the index to insert at
  174. * @param coll the collection to add in iterator order
  175. * @return true if this collection changed
  176. */
  177. public override bool addAll(int index, java.util.Collection<Object> coll)
  178. {
  179. // gets initial size
  180. int sizeBefore = size();
  181. // adds all elements
  182. for (java.util.Iterator<Object> it = coll.iterator(); it.hasNext(); )
  183. {
  184. add(it.next());
  185. }
  186. // compares sizes to detect if collection changed
  187. return sizeBefore != size();
  188. }
  189. //-----------------------------------------------------------------------
  190. /**
  191. * Sets the value at the specified index avoiding duplicates.
  192. * <p>
  193. * The object is set into the specified index.
  194. * Afterwards, any previous duplicate is removed
  195. * If the object is not already in the list then a normal set occurs.
  196. * If it is present, then the old version is removed.
  197. *
  198. * @param index the index to insert at
  199. * @param object the object to set
  200. * @return the previous object
  201. */
  202. public override Object set(int index, Object obj)
  203. {
  204. int pos = indexOf(obj);
  205. Object removed = base.set(index, obj);
  206. if (pos == -1 || pos == index)
  207. {
  208. return removed;
  209. }
  210. // the object is already in the uniq list
  211. // (and it hasn't been swapped with itself)
  212. base.remove(pos); // remove the duplicate by index
  213. setJ.remove(removed); // remove the item deleted by the set
  214. return removed; // return the item deleted by the set
  215. }
  216. public override bool remove(Object obj)
  217. {
  218. bool result = base.remove(obj);
  219. setJ.remove(obj);
  220. return result;
  221. }
  222. public override Object remove(int index)
  223. {
  224. Object result = base.remove(index);
  225. setJ.remove(result);
  226. return result;
  227. }
  228. public override bool removeAll(java.util.Collection<Object> coll)
  229. {
  230. bool result = base.removeAll(coll);
  231. setJ.removeAll(coll);
  232. return result;
  233. }
  234. public override bool retainAll(java.util.Collection<Object> coll)
  235. {
  236. bool result = base.retainAll(coll);
  237. setJ.retainAll(coll);
  238. return result;
  239. }
  240. public override void clear()
  241. {
  242. base.clear();
  243. setJ.clear();
  244. }
  245. public override bool contains(Object obj)
  246. {
  247. return setJ.contains(obj);
  248. }
  249. public override bool containsAll(java.util.Collection<Object> coll)
  250. {
  251. return setJ.containsAll(coll);
  252. }
  253. public override java.util.Iterator<Object> iterator()
  254. {
  255. return new SetListIterator(base.iterator(), setJ);
  256. }
  257. public override java.util.ListIterator<Object> listIterator()
  258. {
  259. return new SetListListIterator(base.listIterator(), setJ);
  260. }
  261. public override java.util.ListIterator<Object> listIterator(int index)
  262. {
  263. return new SetListListIterator(base.listIterator(index), setJ);
  264. }
  265. public override java.util.List<Object> subList(int fromIndex, int toIndex)
  266. {
  267. return new SetUniqueList(base.subList(fromIndex, toIndex), setJ);
  268. }
  269. //-----------------------------------------------------------------------
  270. /**
  271. * Inner class iterator.
  272. */
  273. internal class SetListIterator : AbstractIteratorDecorator
  274. {
  275. protected java.util.Set<Object> set;
  276. protected Object last = null;
  277. protected internal SetListIterator(java.util.Iterator<Object> it, java.util.Set<Object> set)
  278. : base(it)
  279. {
  280. this.set = set;
  281. }
  282. public override Object next()
  283. {
  284. last = base.next();
  285. return last;
  286. }
  287. public override void remove()
  288. {
  289. base.remove();
  290. set.remove(last);
  291. last = null;
  292. }
  293. }
  294. /**
  295. * Inner class iterator.
  296. */
  297. internal class SetListListIterator : AbstractListIteratorDecorator
  298. {
  299. protected java.util.Set<Object> setJ;
  300. protected Object last = null;
  301. protected internal SetListListIterator(java.util.ListIterator<Object> it, java.util.Set<Object> set)
  302. : base(it)
  303. {
  304. this.setJ = set;
  305. }
  306. public override Object next()
  307. {
  308. last = base.next();
  309. return last;
  310. }
  311. public override Object previous()
  312. {
  313. last = base.previous();
  314. return last;
  315. }
  316. public override void remove()
  317. {
  318. base.remove();
  319. setJ.remove(last);
  320. last = null;
  321. }
  322. public override void add(Object obj)
  323. {
  324. if (setJ.contains(obj) == false)
  325. {
  326. base.add(obj);
  327. setJ.add(obj);
  328. }
  329. }
  330. public override void set(Object obj)
  331. {
  332. throw new java.lang.UnsupportedOperationException("ListIterator does not support set");
  333. }
  334. }
  335. }
  336. }