Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

LinkedList.java

00001 package ca.mcgill.sable.util;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * SableUtil, a clean room implementation of the Collection API.     *
00005  * Copyright (C) 1997, 1998 Etienne Gagnon (gagnon@sable.mcgill.ca). *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project of the Sable Research Group,      *
00009  * School of Computer Science, McGill University, Canada             *
00010  * (http://www.sable.mcgill.ca/).  It is understood that any         *
00011  * modification not identified as such is not covered by the         *
00012  * preceding statement.                                              *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this library; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * To submit a bug report, send a comment, or get the latest news on *
00030  * this project and other Sable Research Group projects, please      *
00031  * visit the web site: http://www.sable.mcgill.ca/                   *
00032  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00033 
00034 /*
00035  Reference Version
00036  -----------------
00037  This is the latest official version on which this file is based.
00038  The reference version is: $SableUtilVersion: 1.11 $
00039 
00040  Change History
00041  --------------
00042  A) Notes:
00043 
00044  Please use the following template.  Most recent changes should
00045  appear at the top of the list.
00046 
00047  - Modified on [date (March 1, 1900)] by [name]. [(*) if appropriate]
00048    [description of modification].
00049 
00050  Any Modification flagged with "(*)" was done as a project of the
00051  Sable Research Group, School of Computer Science,
00052  McGill University, Canada (http://www.sable.mcgill.ca/).
00053 
00054  You should add your copyright, using the following template, at
00055  the top of this file, along with other copyrights.
00056 
00057  *                                                                   *
00058  * Modifications by [name] are                                       *
00059  * Copyright (C) [year(s)] [your name (or company)].  All rights     *
00060  * reserved.                                                         *
00061  *                                                                   *
00062 
00063  B) Changes:
00064 
00065  - Modified on June 7, 1998 by Etienne Gagnon (gagnon@sable.mcgill.ca). (*)
00066    Changed the license.
00067 */
00068 
00069 public class LinkedList extends AbstractSequentialList
00070 {
00071     int size;
00072     Node first;
00073     Node last;
00074 
00075     private class LinkedListIterator implements ListIterator
00076     {
00077         private Node next;
00078         private Node prev;
00079         private Node old;
00080         private int nextIndex;
00081         private int prevIndex;
00082         private int localModCount = modCount;
00083 
00084         LinkedListIterator(int index)
00085         {
00086             if(index < size - index)
00087             {
00088                 prev = null;
00089                 next = first;
00090                 nextIndex = 0;
00091                 prevIndex = -1;
00092 
00093                 for(int i = 0; i < index; i++)
00094                 {
00095                     next();
00096                 }
00097             }
00098             else
00099             {
00100                 prev = last;
00101                 next = null;
00102                 nextIndex = size;
00103                 prevIndex = size - 1;
00104 
00105                 for(int i = size; i > index; i--)
00106                 {
00107                     previous();
00108                 }
00109             }
00110         }
00111 
00112         public void set(Object o)
00113         {
00114             if(localModCount != modCount)
00115             {
00116                 throw new ConcurrentModificationException();
00117             }
00118 
00119             if(old == null)
00120             {
00121                 throw new java.util.NoSuchElementException();
00122             }
00123 
00124             old.setElement(o);
00125         }
00126 
00127         public void add(Object o)
00128         {
00129             if(localModCount != modCount)
00130             {
00131                 throw new ConcurrentModificationException();
00132             }
00133 
00134             if(prev == null)
00135             {
00136                 addFirst(o);
00137                 next = first;
00138             }
00139             else if(next == null)
00140             {
00141                 addLast(o);
00142                 next = last;
00143             }
00144             else
00145             {
00146                 Node node = new Node(o);
00147                 node.setPrevious(prev);
00148                 node.setNext(next);
00149                 next = node;
00150 
00151                 modCount++;
00152                 size++;
00153             }
00154 
00155             localModCount = modCount;
00156         }
00157 
00158         public int nextIndex()
00159         {
00160             if(localModCount != modCount)
00161             {
00162                 throw new ConcurrentModificationException();
00163             }
00164 
00165             return nextIndex;
00166         }
00167 
00168         public int previousIndex()
00169         {
00170             if(localModCount != modCount)
00171             {
00172                 throw new ConcurrentModificationException();
00173             }
00174 
00175             return prevIndex;
00176         }
00177 
00178         public boolean hasPrevious()
00179         {
00180             if(localModCount != modCount)
00181             {
00182                 throw new ConcurrentModificationException();
00183             }
00184 
00185             return prevIndex >= 0;
00186         }
00187 
00188         public Object previous()
00189         {
00190             if(localModCount != modCount)
00191             {
00192                 throw new ConcurrentModificationException();
00193             }
00194 
00195             if(prev == null)
00196             {
00197                 throw new java.util.NoSuchElementException();
00198             }
00199 
00200             next = old = prev;
00201             prev = prev.getPrevious();
00202             prevIndex--;
00203             nextIndex--;
00204 
00205             return old.getElement();
00206         }
00207 
00208         public boolean hasNext()
00209         {
00210             if(localModCount != modCount)
00211             {
00212                 throw new ConcurrentModificationException();
00213             }
00214 
00215             return nextIndex < size();
00216         }
00217 
00218         public Object next()
00219         {
00220             if(localModCount != modCount)
00221             {
00222                 throw new ConcurrentModificationException();
00223             }
00224 
00225             if(next == null)
00226             {
00227                 throw new java.util.NoSuchElementException();
00228             }
00229 
00230             prev = old = next;
00231             next = next.getNext();
00232             prevIndex++;
00233             nextIndex++;
00234 
00235             return old.getElement();
00236         }
00237 
00238         public void remove()
00239         {
00240             if(localModCount != modCount)
00241             {
00242                 throw new ConcurrentModificationException();
00243             }
00244 
00245             if(old == null)
00246             {
00247                 throw new java.util.NoSuchElementException();
00248             }
00249 
00250             if(next == old)
00251             {
00252                 next = next.getNext();
00253             }
00254             else
00255             {
00256                 prev = prev.getPrevious();
00257                 prevIndex--;
00258                 nextIndex--;
00259             }
00260 
00261             LinkedList.this.removeNode(old);
00262             localModCount = modCount;
00263             old = null;
00264         }
00265     }
00266 
00267     private class Node
00268     {
00269         private Node previous;
00270         private Node next;
00271         private Object element;
00272 
00273         Node(Object element)
00274         {
00275             this.element = element;
00276         }
00277 
00278         Object getElement()
00279         {
00280             return element;
00281         }
00282 
00283         void setElement(Object element)
00284         {
00285             this.element = element;
00286         }
00287 
00288         Node getPrevious()
00289         {
00290             return previous;
00291         }
00292 
00293         void setPrevious(Node node)
00294         {
00295             if(previous != null)
00296             {
00297                 previous.next = null;
00298             }
00299 
00300             if(node != null)
00301             {
00302                 if(node.next != null)
00303                 {
00304                     node.next.previous = null;
00305                 }
00306 
00307                 node.next = this;
00308             }
00309 
00310             previous = node;
00311         }
00312 
00313         Node getNext()
00314         {
00315             return next;
00316         }
00317 
00318         void setNext(Node node)
00319         {
00320             if(next != null)
00321             {
00322                 next.previous = null;
00323             }
00324 
00325             if(node != null)
00326             {
00327                 if(node.previous != null)
00328                 {
00329                     node.previous.next = null;
00330                 }
00331 
00332                 node.previous = this;
00333             }
00334 
00335             next = node;
00336         }
00337 
00338     }
00339 
00340     public LinkedList()
00341     {
00342     }
00343     public LinkedList(Collection c)
00344     {
00345         ListIterator j = listIterator();
00346 
00347         for(Iterator i = c.iterator(); i.hasNext();)
00348         {
00349             j.add(i.next());
00350             j.next();
00351         }
00352     }
00353     public void addFirst(Object o)
00354     {
00355         Node node = new Node(o);
00356 
00357         if(first == null)
00358         {
00359             first = node;
00360             last = node;
00361         }
00362         else
00363         {
00364             first.setPrevious(node);
00365             first = node;
00366         }
00367 
00368         modCount++;
00369         size++;
00370     }
00371     public void addLast(Object o)
00372     {
00373         Node node = new Node(o);
00374 
00375         if(last == null)
00376         {
00377             last = node;
00378             first = node;
00379         }
00380         else
00381         {
00382             last.setNext(node);
00383             last = node;
00384         }
00385 
00386         modCount++;
00387         size++;
00388     }
00389     public void clear()
00390     {
00391         first = last = null;
00392     }
00393     public Object getFirst()
00394     {
00395         if(first == null)
00396         {
00397             throw new java.util.NoSuchElementException();
00398         }
00399 
00400         return first.getElement();
00401     }
00402     public Object getLast()
00403     {
00404         if(last == null)
00405         {
00406             throw new java.util.NoSuchElementException();
00407         }
00408 
00409         return last.getElement();
00410     }
00411     public ListIterator listIterator(int index)
00412     {
00413         return new LinkedListIterator(index);
00414     }
00415     public Object removeFirst()
00416     {
00417         if(first == null)
00418         {
00419             throw new java.util.NoSuchElementException();
00420         }
00421 
00422         Object old = first.getElement();
00423         removeNode(first);
00424 
00425         return old;
00426     }
00427     public Object removeLast()
00428     {
00429         if(last == null)
00430         {
00431             throw new java.util.NoSuchElementException();
00432         }
00433 
00434         Object old = last.getElement();
00435         removeNode(last);
00436 
00437         return old;
00438     }
00439     private void removeNode(Node node)
00440     {
00441         Node prev = node.getPrevious();
00442         Node next = node.getNext();
00443 
00444         if(prev == null)
00445         {
00446             first = next;
00447         }
00448         else
00449         {
00450             prev.setNext(next);
00451         }
00452 
00453         if(next == null)
00454         {
00455             last = prev;
00456         }
00457         else
00458         {
00459             next.setPrevious(prev);
00460         }
00461 
00462         modCount++;
00463         size--;
00464     }
00465     public int size()
00466     {
00467         return size;
00468     }
00469 }

Generated at Thu Feb 7 06:49:37 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001