PageRenderTime 31ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/gadfly/nofs
C# | 1160 lines | 731 code | 110 blank | 319 comment | 84 complexity | e7d640eb2e677a1a9d95514480bb620e 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;
  18. namespace org.apache.commons.collections.list
  19. {
  20. /**
  21. * An abstract implementation of a linked list which provides numerous points for
  22. * subclasses to override.
  23. * <p>
  24. * Overridable methods are provided to change the storage node and to change how
  25. * nodes are added to and removed. Hopefully, all you need for unusual subclasses
  26. * is here.
  27. *
  28. * @since Commons Collections 3.0
  29. * @version $Revision$ $Date$
  30. *
  31. * @author Rich Dougherty
  32. * @author Phil Steitz
  33. * @author Stephen Colebourne
  34. */
  35. public abstract class AbstractLinkedList : java.util.List<Object>
  36. {
  37. /*
  38. * Implementation notes:
  39. * - a standard circular doubly-linked list
  40. * - a marker node is stored to mark the start and the end of the list
  41. * - node creation and removal always occurs through createNode() and
  42. * removeNode().
  43. * - a modification count is kept, with the same semantics as
  44. * {@link java.util.LinkedList}.
  45. * - respects {@link AbstractList#modCount}
  46. */
  47. /**
  48. * A {@link Node} which indicates the start and end of the list and does not
  49. * hold a value. The value of <code>next</code> is the first item in the
  50. * list. The value of of <code>previous</code> is the last item in the list.
  51. */
  52. [NonSerialized]
  53. protected internal Node header;
  54. /** The size of the list */
  55. [NonSerialized]
  56. protected int sizeJ;
  57. /** Modification count for iterators */
  58. [NonSerialized]
  59. protected internal int modCount;
  60. /**
  61. * Constructor that does nothing intended for deserialization.
  62. * <p>
  63. * If this constructor is used by a java.io.Serializable subclass then the init()
  64. * method must be called.
  65. */
  66. protected AbstractLinkedList()
  67. : base()
  68. {
  69. }
  70. /**
  71. * Constructs a list copying data from the specified collection.
  72. *
  73. * @param coll the collection to copy
  74. */
  75. protected AbstractLinkedList(java.util.Collection<Object> coll)
  76. : base()
  77. {
  78. init();
  79. addAll(coll);
  80. }
  81. /**
  82. * The equivalent of a default constructor, broken out so it can be called
  83. * by any constructor and by <code>readObject</code>.
  84. * Subclasses which override this method should make sure they call super,
  85. * so the list is initialised properly.
  86. */
  87. protected virtual void init()
  88. {
  89. header = createHeaderNode();
  90. }
  91. //-----------------------------------------------------------------------
  92. public virtual int size()
  93. {
  94. return sizeJ;
  95. }
  96. public virtual bool isEmpty()
  97. {
  98. return (size() == 0);
  99. }
  100. public virtual Object get(int index)
  101. {
  102. Node node = getNode(index, false);
  103. return node.getValue();
  104. }
  105. //-----------------------------------------------------------------------
  106. public virtual java.util.Iterator<Object> iterator()
  107. {
  108. return listIterator();
  109. }
  110. public virtual java.util.ListIterator<Object> listIterator()
  111. {
  112. return new LinkedListIterator(this, 0);
  113. }
  114. public virtual java.util.ListIterator<Object> listIterator(int fromIndex)
  115. {
  116. return new LinkedListIterator(this, fromIndex);
  117. }
  118. //-----------------------------------------------------------------------
  119. public virtual int indexOf(Object value)
  120. {
  121. int i = 0;
  122. for (Node node = header.next; node != header; node = node.next)
  123. {
  124. if (isEqualValue(node.getValue(), value))
  125. {
  126. return i;
  127. }
  128. i++;
  129. }
  130. return -1;
  131. }
  132. public virtual int lastIndexOf(Object value)
  133. {
  134. int i = sizeJ - 1;
  135. for (Node node = header.previous; node != header; node = node.previous)
  136. {
  137. if (isEqualValue(node.getValue(), value))
  138. {
  139. return i;
  140. }
  141. i--;
  142. }
  143. return -1;
  144. }
  145. public virtual bool contains(Object value)
  146. {
  147. return indexOf(value) != -1;
  148. }
  149. public virtual bool containsAll(java.util.Collection<Object> coll)
  150. {
  151. java.util.Iterator<Object> it = coll.iterator();
  152. while (it.hasNext())
  153. {
  154. if (contains(it.next()) == false)
  155. {
  156. return false;
  157. }
  158. }
  159. return true;
  160. }
  161. //-----------------------------------------------------------------------
  162. public virtual Object[] toArray()
  163. {
  164. return toArray(new Object[sizeJ]);
  165. }
  166. public virtual Object[] toArray<Object>(Object[] array)
  167. {
  168. // Extend the array if needed
  169. if (array.Length < sizeJ)
  170. {
  171. // Basties note: Why this next two lines, we only return an array of object instances
  172. //Class componentType = array.getClass().getComponentType();
  173. //array = (Object[]) java.lang.reflect.Array.newInstance(componentType, size);
  174. array = new Object[sizeJ];
  175. }
  176. // Copy the values into the array
  177. int i = 0;
  178. for (Node node = header.next; node != header; node = node.next, i++)
  179. {
  180. array[i] = (Object)node.getValue();
  181. }
  182. // Set the value after the last value to null
  183. if (array.Length > sizeJ)
  184. {
  185. array[sizeJ] = default(Object);
  186. }
  187. return array;
  188. }
  189. /**
  190. * Gets a sublist of the main list.
  191. *
  192. * @param fromIndexInclusive the index to start from
  193. * @param toIndexExclusive the index to end at
  194. * @return the new sublist
  195. */
  196. public virtual java.util.List<Object> subList(int fromIndexInclusive, int toIndexExclusive)
  197. {
  198. return new LinkedSubList(this, fromIndexInclusive, toIndexExclusive);
  199. }
  200. //-----------------------------------------------------------------------
  201. public virtual bool add(Object value)
  202. {
  203. addLast(value);
  204. return true;
  205. }
  206. public virtual void add(int index, Object value)
  207. {
  208. Node node = getNode(index, true);
  209. addNodeBefore(node, value);
  210. }
  211. public virtual bool addAll(java.util.Collection<Object> coll)
  212. {
  213. return addAll(sizeJ, coll);
  214. }
  215. public virtual bool addAll(int index, java.util.Collection<Object> coll)
  216. {
  217. Node node = getNode(index, true);
  218. for (java.util.Iterator<Object> itr = coll.iterator(); itr.hasNext(); )
  219. {
  220. Object value = itr.next();
  221. addNodeBefore(node, value);
  222. }
  223. return true;
  224. }
  225. //-----------------------------------------------------------------------
  226. public virtual Object remove(int index)
  227. {
  228. Node node = getNode(index, false);
  229. Object oldValue = node.getValue();
  230. removeNode(node);
  231. return oldValue;
  232. }
  233. public virtual bool remove(Object value)
  234. {
  235. for (Node node = header.next; node != header; node = node.next)
  236. {
  237. if (isEqualValue(node.getValue(), value))
  238. {
  239. removeNode(node);
  240. return true;
  241. }
  242. }
  243. return false;
  244. }
  245. public virtual bool removeAll(java.util.Collection<Object> coll)
  246. {
  247. bool modified = false;
  248. java.util.Iterator<Object> it = iterator();
  249. while (it.hasNext())
  250. {
  251. if (coll.contains(it.next()))
  252. {
  253. it.remove();
  254. modified = true;
  255. }
  256. }
  257. return modified;
  258. }
  259. //-----------------------------------------------------------------------
  260. public virtual bool retainAll(java.util.Collection<Object> coll)
  261. {
  262. bool modified = false;
  263. java.util.Iterator<Object> it = iterator();
  264. while (it.hasNext())
  265. {
  266. if (coll.contains(it.next()) == false)
  267. {
  268. it.remove();
  269. modified = true;
  270. }
  271. }
  272. return modified;
  273. }
  274. public virtual Object set(int index, Object value)
  275. {
  276. Node node = getNode(index, false);
  277. Object oldValue = node.getValue();
  278. updateNode(node, value);
  279. return oldValue;
  280. }
  281. public virtual void clear()
  282. {
  283. removeAllNodes();
  284. }
  285. //-----------------------------------------------------------------------
  286. public virtual Object getFirst()
  287. {
  288. Node node = header.next;
  289. if (node == header)
  290. {
  291. throw new java.util.NoSuchElementException();
  292. }
  293. return node.getValue();
  294. }
  295. public virtual Object getLast()
  296. {
  297. Node node = header.previous;
  298. if (node == header)
  299. {
  300. throw new java.util.NoSuchElementException();
  301. }
  302. return node.getValue();
  303. }
  304. public virtual bool addFirst(Object o)
  305. {
  306. addNodeAfter(header, o);
  307. return true;
  308. }
  309. public virtual bool addLast(Object o)
  310. {
  311. addNodeBefore(header, o);
  312. return true;
  313. }
  314. public virtual Object removeFirst()
  315. {
  316. Node node = header.next;
  317. if (node == header)
  318. {
  319. throw new java.util.NoSuchElementException();
  320. }
  321. Object oldValue = node.getValue();
  322. removeNode(node);
  323. return oldValue;
  324. }
  325. public virtual Object removeLast()
  326. {
  327. Node node = header.previous;
  328. if (node == header)
  329. {
  330. throw new java.util.NoSuchElementException();
  331. }
  332. Object oldValue = node.getValue();
  333. removeNode(node);
  334. return oldValue;
  335. }
  336. //-----------------------------------------------------------------------
  337. public override bool Equals(Object obj)
  338. {
  339. if (obj == this)
  340. {
  341. return true;
  342. }
  343. if (obj is java.util.List<Object> == false)
  344. {
  345. return false;
  346. }
  347. java.util.List<Object> other = (java.util.List<Object>)obj;
  348. if (other.size() != size())
  349. {
  350. return false;
  351. }
  352. java.util.ListIterator<Object> it1 = listIterator();
  353. java.util.ListIterator<Object> it2 = other.listIterator();
  354. while (it1.hasNext() && it2.hasNext())
  355. {
  356. Object o1 = it1.next();
  357. Object o2 = it2.next();
  358. if (!(o1 == null ? o2 == null : o1.equals(o2)))
  359. return false;
  360. }
  361. return !(it1.hasNext() || it2.hasNext());
  362. }
  363. public override int GetHashCode()
  364. {
  365. int hashCode = 1;
  366. java.util.Iterator<Object> it = iterator();
  367. while (it.hasNext())
  368. {
  369. Object obj = it.next();
  370. hashCode = 31 * hashCode + (obj == null ? 0 : obj.GetHashCode());
  371. }
  372. return hashCode;
  373. }
  374. public override String ToString()
  375. {
  376. if (size() == 0)
  377. {
  378. return "[]";
  379. }
  380. java.lang.StringBuffer buf = new java.lang.StringBuffer(16 * size());
  381. buf.append("[");
  382. java.util.Iterator<Object> it = iterator();
  383. bool hasNext = it.hasNext();
  384. while (hasNext)
  385. {
  386. Object value = it.next();
  387. buf.append(value == this ? "(this Collection)" : value);
  388. hasNext = it.hasNext();
  389. if (hasNext)
  390. {
  391. buf.append(", ");
  392. }
  393. }
  394. buf.append("]");
  395. return buf.toString();
  396. }
  397. //-----------------------------------------------------------------------
  398. /**
  399. * Compares two values for equals.
  400. * This implementation uses the equals method.
  401. * Subclasses can override this to match differently.
  402. *
  403. * @param value1 the first value to compare, may be null
  404. * @param value2 the second value to compare, may be null
  405. * @return true if equal
  406. */
  407. protected virtual bool isEqualValue(Object value1, Object value2)
  408. {
  409. return (value1 == value2 || (value1 == null ? false : value1.equals(value2)));
  410. }
  411. /**
  412. * Updates the node with a new value.
  413. * This implementation sets the value on the node.
  414. * Subclasses can override this to record the change.
  415. *
  416. * @param node node to update
  417. * @param value new value of the node
  418. */
  419. protected virtual void updateNode(Node node, Object value)
  420. {
  421. node.setValue(value);
  422. }
  423. /**
  424. * Creates a new node with previous, next and element all set to null.
  425. * This implementation creates a new empty Node.
  426. * Subclasses can override this to create a different class.
  427. *
  428. * @return newly created node
  429. */
  430. protected virtual Node createHeaderNode()
  431. {
  432. return new Node();
  433. }
  434. /**
  435. * Creates a new node with the specified properties.
  436. * This implementation creates a new Node with data.
  437. * Subclasses can override this to create a different class.
  438. *
  439. * @param value value of the new node
  440. */
  441. protected virtual Node createNode(Object value)
  442. {
  443. return new Node(value);
  444. }
  445. /**
  446. * Creates a new node with the specified object as its
  447. * <code>value</code> and inserts it before <code>node</code>.
  448. * <p>
  449. * This implementation uses {@link #createNode(Object)} and
  450. * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
  451. *
  452. * @param node node to insert before
  453. * @param value value of the newly added node
  454. * @throws NullPointerException if <code>node</code> is null
  455. */
  456. protected internal virtual void addNodeBefore(Node node, Object value)
  457. {
  458. Node newNode = createNode(value);
  459. addNode(newNode, node);
  460. }
  461. /**
  462. * Creates a new node with the specified object as its
  463. * <code>value</code> and inserts it after <code>node</code>.
  464. * <p>
  465. * This implementation uses {@link #createNode(Object)} and
  466. * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
  467. *
  468. * @param node node to insert after
  469. * @param value value of the newly added node
  470. * @throws NullPointerException if <code>node</code> is null
  471. */
  472. protected virtual void addNodeAfter(Node node, Object value)
  473. {
  474. Node newNode = createNode(value);
  475. addNode(newNode, node.next);
  476. }
  477. /**
  478. * Inserts a new node into the list.
  479. *
  480. * @param nodeToInsert new node to insert
  481. * @param insertBeforeNode node to insert before
  482. * @throws NullPointerException if either node is null
  483. */
  484. protected virtual void addNode(Node nodeToInsert, Node insertBeforeNode)
  485. {
  486. nodeToInsert.next = insertBeforeNode;
  487. nodeToInsert.previous = insertBeforeNode.previous;
  488. insertBeforeNode.previous.next = nodeToInsert;
  489. insertBeforeNode.previous = nodeToInsert;
  490. sizeJ++;
  491. modCount++;
  492. }
  493. /**
  494. * Removes the specified node from the list.
  495. *
  496. * @param node the node to remove
  497. * @throws NullPointerException if <code>node</code> is null
  498. */
  499. protected internal virtual void removeNode(Node node)
  500. {
  501. node.previous.next = node.next;
  502. node.next.previous = node.previous;
  503. sizeJ--;
  504. modCount++;
  505. }
  506. /**
  507. * Removes all nodes by resetting the circular list marker.
  508. */
  509. protected virtual void removeAllNodes()
  510. {
  511. header.next = header;
  512. header.previous = header;
  513. sizeJ = 0;
  514. modCount++;
  515. }
  516. /**
  517. * Gets the node at a particular index.
  518. *
  519. * @param index the index, starting from 0
  520. * @param endMarkerAllowed whether or not the end marker can be returned if
  521. * startIndex is set to the list's size
  522. * @throws IndexOutOfBoundsException if the index is less than 0; equal to
  523. * the size of the list and endMakerAllowed is false; or greater than the
  524. * size of the list
  525. */
  526. protected internal virtual Node getNode(int index, bool endMarkerAllowed)
  527. {//throws IndexOutOfBoundsException {
  528. // Check the index is within the bounds
  529. if (index < 0)
  530. {
  531. throw new java.lang.IndexOutOfBoundsException("Couldn't get the node: " +
  532. "index (" + index + ") less than zero.");
  533. }
  534. if (!endMarkerAllowed && index == sizeJ)
  535. {
  536. throw new java.lang.IndexOutOfBoundsException("Couldn't get the node: " +
  537. "index (" + index + ") is the size of the list.");
  538. }
  539. if (index > sizeJ)
  540. {
  541. throw new java.lang.IndexOutOfBoundsException("Couldn't get the node: " +
  542. "index (" + index + ") greater than the size of the " +
  543. "list (" + sizeJ + ").");
  544. }
  545. // Search the list and get the node
  546. Node node;
  547. if (index < (sizeJ / 2))
  548. {
  549. // Search forwards
  550. node = header.next;
  551. for (int currentIndex = 0; currentIndex < index; currentIndex++)
  552. {
  553. node = node.next;
  554. }
  555. }
  556. else
  557. {
  558. // Search backwards
  559. node = header;
  560. for (int currentIndex = sizeJ; currentIndex > index; currentIndex--)
  561. {
  562. node = node.previous;
  563. }
  564. }
  565. return node;
  566. }
  567. //-----------------------------------------------------------------------
  568. /**
  569. * Creates an iterator for the sublist.
  570. *
  571. * @param subList the sublist to get an iterator for
  572. */
  573. protected internal virtual java.util.Iterator<Object> createSubListIterator(LinkedSubList subList)
  574. {
  575. return createSubListListIterator(subList, 0);
  576. }
  577. /**
  578. * Creates a list iterator for the sublist.
  579. *
  580. * @param subList the sublist to get an iterator for
  581. * @param fromIndex the index to start from, relative to the sublist
  582. */
  583. protected internal virtual java.util.ListIterator<Object> createSubListListIterator(LinkedSubList subList, int fromIndex)
  584. {
  585. return new LinkedSubListIterator(subList, fromIndex);
  586. }
  587. //-----------------------------------------------------------------------
  588. /**
  589. * Serializes the data held in this object to the stream specified.
  590. * <p>
  591. * The first java.io.Serializable subclass must call this method from
  592. * <code>writeObject</code>.
  593. */
  594. protected virtual void doWriteObject(java.io.ObjectOutputStream outputStream)
  595. {//throws IOException {
  596. // Write the size so we know how many nodes to read back
  597. outputStream.writeInt(size());
  598. for (java.util.Iterator<Object> itr = iterator(); itr.hasNext(); )
  599. {
  600. outputStream.writeObject(itr.next());
  601. }
  602. }
  603. /**
  604. * Deserializes the data held in this object to the stream specified.
  605. * <p>
  606. * The first java.io.Serializable subclass must call this method from
  607. * <code>readObject</code>.
  608. */
  609. protected virtual void doReadObject(java.io.ObjectInputStream inputStream)
  610. {//throws IOException, ClassNotFoundException {
  611. init();
  612. int size = inputStream.readInt();
  613. for (int i = 0; i < size; i++)
  614. {
  615. add(inputStream.readObject());
  616. }
  617. }
  618. }
  619. //-----------------------------------------------------------------------
  620. /**
  621. * A node within the linked list.
  622. * <p>
  623. * From Commons Collections 3.1, all access to the <code>value</code> property
  624. * is via the methods on this class.
  625. */
  626. public class Node
  627. {
  628. /** A pointer to the node before this node */
  629. protected internal Node previous;
  630. /** A pointer to the node after this node */
  631. protected internal Node next;
  632. /** The object contained within this node */
  633. protected Object value;
  634. /**
  635. * Constructs a new header node.
  636. */
  637. protected internal Node()
  638. : base()
  639. {
  640. previous = this;
  641. next = this;
  642. }
  643. /**
  644. * Constructs a new node.
  645. *
  646. * @param value the value to store
  647. */
  648. protected internal Node(Object value)
  649. : base()
  650. {
  651. this.value = value;
  652. }
  653. /**
  654. * Constructs a new node.
  655. *
  656. * @param previous the previous node in the list
  657. * @param next the next node in the list
  658. * @param value the value to store
  659. */
  660. protected internal Node(Node previous, Node next, Object value)
  661. : base()
  662. {
  663. this.previous = previous;
  664. this.next = next;
  665. this.value = value;
  666. }
  667. /**
  668. * Gets the value of the node.
  669. *
  670. * @return the value
  671. * @since Commons Collections 3.1
  672. */
  673. protected internal virtual Object getValue()
  674. {
  675. return value;
  676. }
  677. /**
  678. * Sets the value of the node.
  679. *
  680. * @param value the value
  681. * @since Commons Collections 3.1
  682. */
  683. protected internal virtual void setValue(Object value)
  684. {
  685. this.value = value;
  686. }
  687. /**
  688. * Gets the previous node.
  689. *
  690. * @return the previous node
  691. * @since Commons Collections 3.1
  692. */
  693. protected internal virtual Node getPreviousNode()
  694. {
  695. return previous;
  696. }
  697. /**
  698. * Sets the previous node.
  699. *
  700. * @param previous the previous node
  701. * @since Commons Collections 3.1
  702. */
  703. protected internal virtual void setPreviousNode(Node previous)
  704. {
  705. this.previous = previous;
  706. }
  707. /**
  708. * Gets the next node.
  709. *
  710. * @return the next node
  711. * @since Commons Collections 3.1
  712. */
  713. protected virtual Node getNextNode()
  714. {
  715. return next;
  716. }
  717. /**
  718. * Sets the next node.
  719. *
  720. * @param next the next node
  721. * @since Commons Collections 3.1
  722. */
  723. protected virtual void setNextNode(Node next)
  724. {
  725. this.next = next;
  726. }
  727. }
  728. //-----------------------------------------------------------------------
  729. /**
  730. * A list iterator over the linked list.
  731. */
  732. public class LinkedListIterator : java.util.ListIterator<Object>, OrderedIterator
  733. {
  734. /** The parent list */
  735. protected readonly AbstractLinkedList parent;
  736. /**
  737. * The node that will be returned by {@link #next()}. If this is equal
  738. * to {@link AbstractLinkedList#header} then there are no more values to return.
  739. */
  740. protected Node nextJ;
  741. /**
  742. * The index of {@link #next}.
  743. */
  744. protected int nextIndexJ;
  745. /**
  746. * The last node that was returned by {@link #next()} or {@link
  747. * #previous()}. Set to <code>null</code> if {@link #next()} or {@link
  748. * #previous()} haven't been called, or if the node has been removed
  749. * with {@link #remove()} or a new node added with {@link #add(Object)}.
  750. * Should be accessed through {@link #getLastNodeReturned()} to enforce
  751. * this behaviour.
  752. */
  753. protected Node current;
  754. /**
  755. * The modification count that the list is expected to have. If the list
  756. * doesn't have this count, then a
  757. * {@link java.util.ConcurrentModificationException} may be thrown by
  758. * the operations.
  759. */
  760. protected int expectedModCount;
  761. /**
  762. * Create a ListIterator for a list.
  763. *
  764. * @param parent the parent list
  765. * @param fromIndex the index to start at
  766. */
  767. protected internal LinkedListIterator(AbstractLinkedList parent, int fromIndex)
  768. : base()
  769. {// throws IndexOutOfBoundsException {
  770. this.parent = parent;
  771. this.expectedModCount = parent.modCount;
  772. this.nextJ = parent.getNode(fromIndex, true);
  773. this.nextIndexJ = fromIndex;
  774. }
  775. /**
  776. * Checks the modification count of the list is the value that this
  777. * object expects.
  778. *
  779. * @throws ConcurrentModificationException If the list's modification
  780. * count isn't the value that was expected.
  781. */
  782. protected virtual void checkModCount()
  783. {
  784. if (parent.modCount != expectedModCount)
  785. {
  786. throw new java.util.ConcurrentModificationException();
  787. }
  788. }
  789. /**
  790. * Gets the last node returned.
  791. *
  792. * @throws IllegalStateException If {@link #next()} or
  793. * {@link #previous()} haven't been called, or if the node has been removed
  794. * with {@link #remove()} or a new node added with {@link #add(Object)}.
  795. */
  796. protected virtual Node getLastNodeReturned()
  797. {//throws IllegalStateException {
  798. if (current == null)
  799. {
  800. throw new java.lang.IllegalStateException();
  801. }
  802. return current;
  803. }
  804. public virtual bool hasNext()
  805. {
  806. return nextJ != parent.header;
  807. }
  808. public virtual Object next()
  809. {
  810. checkModCount();
  811. if (!hasNext())
  812. {
  813. throw new java.util.NoSuchElementException("No element at index " + nextIndexJ + ".");
  814. }
  815. Object value = nextJ.getValue();
  816. current = nextJ;
  817. nextJ = nextJ.next;
  818. nextIndexJ++;
  819. return value;
  820. }
  821. public virtual bool hasPrevious()
  822. {
  823. return nextJ.previous != parent.header;
  824. }
  825. public virtual Object previous()
  826. {
  827. checkModCount();
  828. if (!hasPrevious())
  829. {
  830. throw new java.util.NoSuchElementException("Already at start of list.");
  831. }
  832. nextJ = nextJ.previous;
  833. Object value = nextJ.getValue();
  834. current = nextJ;
  835. nextIndexJ--;
  836. return value;
  837. }
  838. public virtual int nextIndex()
  839. {
  840. return nextIndexJ;
  841. }
  842. public virtual int previousIndex()
  843. {
  844. // not normally overridden, as relative to nextIndex()
  845. return nextIndex() - 1;
  846. }
  847. public virtual void remove()
  848. {
  849. checkModCount();
  850. if (current == nextJ)
  851. {
  852. // remove() following previous()
  853. nextJ = nextJ.next;
  854. parent.removeNode(getLastNodeReturned());
  855. }
  856. else
  857. {
  858. // remove() following next()
  859. parent.removeNode(getLastNodeReturned());
  860. nextIndexJ--;
  861. }
  862. current = null;
  863. expectedModCount++;
  864. }
  865. public virtual void set(Object obj)
  866. {
  867. checkModCount();
  868. getLastNodeReturned().setValue(obj);
  869. }
  870. public virtual void add(Object obj)
  871. {
  872. checkModCount();
  873. parent.addNodeBefore(nextJ, obj);
  874. current = null;
  875. nextIndexJ++;
  876. expectedModCount++;
  877. }
  878. }
  879. //-----------------------------------------------------------------------
  880. /**
  881. * A list iterator over the linked sub list.
  882. */
  883. public class LinkedSubListIterator : LinkedListIterator
  884. {
  885. /** The parent list */
  886. protected readonly LinkedSubList sub;
  887. protected internal LinkedSubListIterator(LinkedSubList sub, int startIndex)
  888. : base(sub.parent, startIndex + sub.offset)
  889. {
  890. this.sub = sub;
  891. }
  892. public override bool hasNext()
  893. {
  894. return (nextIndex() < sub.sizeJ);
  895. }
  896. public override bool hasPrevious()
  897. {
  898. return (previousIndex() >= 0);
  899. }
  900. public override int nextIndex()
  901. {
  902. return (base.nextIndex() - sub.offset);
  903. }
  904. public override void add(Object obj)
  905. {
  906. base.add(obj);
  907. sub.expectedModCount = parent.modCount;
  908. sub.sizeJ++;
  909. }
  910. public override void remove()
  911. {
  912. base.remove();
  913. sub.expectedModCount = parent.modCount;
  914. sub.sizeJ--;
  915. }
  916. }
  917. //-----------------------------------------------------------------------
  918. /**
  919. * The sublist implementation for AbstractLinkedList.
  920. */
  921. public class LinkedSubList : java.util.AbstractList<Object>
  922. {
  923. /** The main list */
  924. internal AbstractLinkedList parent;
  925. /** Offset from the main list */
  926. internal int offset;
  927. /** Sublist size */
  928. internal int sizeJ;
  929. /** Sublist modCount */
  930. internal int expectedModCount;
  931. protected internal LinkedSubList(AbstractLinkedList parent, int fromIndex, int toIndex)
  932. {
  933. if (fromIndex < 0)
  934. {
  935. throw new java.lang.IndexOutOfBoundsException("fromIndex = " + fromIndex);
  936. }
  937. if (toIndex > parent.size())
  938. {
  939. throw new java.lang.IndexOutOfBoundsException("toIndex = " + toIndex);
  940. }
  941. if (fromIndex > toIndex)
  942. {
  943. throw new java.lang.IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
  944. }
  945. this.parent = parent;
  946. this.offset = fromIndex;
  947. this.sizeJ = toIndex - fromIndex;
  948. this.expectedModCount = parent.modCount;
  949. }
  950. public override int size()
  951. {
  952. checkModCount();
  953. return sizeJ;
  954. }
  955. public override Object get(int index)
  956. {
  957. rangeCheck(index, sizeJ);
  958. checkModCount();
  959. return parent.get(index + offset);
  960. }
  961. public override void add(int index, Object obj)
  962. {
  963. rangeCheck(index, sizeJ + 1);
  964. checkModCount();
  965. parent.add(index + offset, obj);
  966. expectedModCount = parent.modCount;
  967. sizeJ++;
  968. modCount++;
  969. }
  970. public override Object remove(int index)
  971. {
  972. rangeCheck(index, sizeJ);
  973. checkModCount();
  974. Object result = parent.remove(index + offset);
  975. expectedModCount = parent.modCount;
  976. sizeJ--;
  977. modCount++;
  978. return result;
  979. }
  980. public override bool addAll(java.util.Collection<Object> coll)
  981. {
  982. return addAll(sizeJ, coll);
  983. }
  984. public override bool addAll(int index, java.util.Collection<Object> coll)
  985. {
  986. rangeCheck(index, sizeJ + 1);
  987. int cSize = coll.size();
  988. if (cSize == 0)
  989. {
  990. return false;
  991. }
  992. checkModCount();
  993. parent.addAll(offset + index, coll);
  994. expectedModCount = parent.modCount;
  995. sizeJ += cSize;
  996. modCount++;
  997. return true;
  998. }
  999. public override Object set(int index, Object obj)
  1000. {
  1001. rangeCheck(index, sizeJ);
  1002. checkModCount();
  1003. return parent.set(index + offset, obj);
  1004. }
  1005. public override void clear()
  1006. {
  1007. checkModCount();
  1008. java.util.Iterator<Object> it = iterator();
  1009. while (it.hasNext())
  1010. {
  1011. it.next();
  1012. it.remove();
  1013. }
  1014. }
  1015. public override java.util.Iterator<Object> iterator()
  1016. {
  1017. checkModCount();
  1018. return parent.createSubListIterator(this);
  1019. }
  1020. public override java.util.ListIterator<Object> listIterator(int index)
  1021. {
  1022. rangeCheck(index, sizeJ + 1);
  1023. checkModCount();
  1024. return parent.createSubListListIterator(this, index);
  1025. }
  1026. public override java.util.List<Object> subList(int fromIndexInclusive, int toIndexExclusive)
  1027. {
  1028. return new LinkedSubList(parent, fromIndexInclusive + offset, toIndexExclusive + offset);
  1029. }
  1030. protected virtual void rangeCheck(int index, int beyond)
  1031. {
  1032. if (index < 0 || index >= beyond)
  1033. {
  1034. throw new java.lang.IndexOutOfBoundsException("Index '" + index + "' out of bounds for size '" + sizeJ + "'");
  1035. }
  1036. }
  1037. protected virtual void checkModCount()
  1038. {
  1039. if (parent.modCount != expectedModCount)
  1040. {
  1041. throw new java.util.ConcurrentModificationException();
  1042. }
  1043. }
  1044. }
  1045. //! @see org.apache.commons.collections.listCursorableLinkedList - Subclass Public... adding for work!
  1046. public class PublicLinkedListIterator : LinkedListIterator
  1047. {
  1048. protected internal PublicLinkedListIterator(AbstractLinkedList parent, int fromIndex) : base (parent,fromIndex){}
  1049. }
  1050. }