00001 package ca.mcgill.sable.util;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
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 }