1 19 20 package gnu.trove; 21 22 import java.io.*; 23 import java.util.AbstractSequentialList ; 24 import java.util.ListIterator ; 25 import java.util.NoSuchElementException ; 26 27 57 58 public class TLinkedList<T extends TLinkable> extends AbstractSequentialList <T> 59 implements Externalizable { 60 61 static final long serialVersionUID = 1L; 62 63 64 65 protected T _head; 66 67 protected T _tail; 68 69 protected int _size = 0; 70 71 75 public TLinkedList() { 76 super(); 77 } 78 79 91 public ListIterator <T> listIterator(int index) { 92 return new IteratorImpl(index); 93 } 94 95 100 public int size() { 101 return _size; 102 } 103 104 112 public void add(int index, T linkable) { 113 if (index < 0 || index > size()) { 114 throw new IndexOutOfBoundsException ("index:" + index); 115 } 116 insert(index,linkable); 117 } 118 119 125 public boolean add(T linkable) { 126 insert(_size, linkable); 127 return true; 128 } 129 130 135 public void addFirst(T linkable) { 136 insert(0, linkable); 137 } 138 139 144 public void addLast(T linkable) { 145 insert(size(), linkable); 146 } 147 148 152 public void clear() { 153 if (null != _head) { 154 for (TLinkable link = _head.getNext(); 155 link != null; 156 link = link.getNext()) { 157 TLinkable prev = link.getPrevious(); 158 prev.setNext(null); 159 link.setPrevious(null); 160 } 161 _head = _tail = null; 162 } 163 _size = 0; 164 } 165 166 177 public Object [] toArray() { 178 Object [] o = new Object [_size]; 179 int i = 0; 180 for (TLinkable link = _head; link != null; link = link.getNext()) { 181 o[i++] = link; 182 } 183 return o; 184 } 185 186 196 public Object [] toUnlinkedArray() { 197 Object [] o = new Object [_size]; 198 int i = 0; 199 for (T link = _head, tmp = null; link != null; i++) { 200 o[i] = link; 201 tmp = link; 202 link = (T) link.getNext(); 203 tmp.setNext(null); tmp.setPrevious(null); 205 } 206 _size = 0; _head = _tail = null; 208 return o; 209 } 210 211 217 public boolean contains(Object o) { 218 for (TLinkable link = _head; link != null; link = link.getNext()) { 219 if (o.equals(link)) { 220 return true; 221 } 222 } 223 return false; 224 } 225 226 227 230 @Override 231 public T get(int index) { 232 if (index == 0) return _head; 234 if (index == _size - 1) return _tail; 235 236 if (index < 0 || index >= _size ) { 238 throw new IndexOutOfBoundsException ("Index: " + index + ", Size: " + _size); 239 } 240 241 if (index > (_size >> 1)) { 243 int position = _size - 1; 244 T node = _tail; 245 246 while ( position > index ) { 247 node = ( T ) node.getPrevious(); 248 position--; 249 } 250 251 return node; 252 } 253 else { 254 int position = 0; 255 T node = _head; 256 257 while( position < index ) { 258 node = ( T ) node.getNext(); 259 position++; 260 } 261 262 return node; 263 } 264 } 265 266 267 272 public T getFirst() { 273 return _head; 274 } 275 276 281 public T getLast() { 282 return _tail; 283 } 284 285 290 public T removeFirst() { 291 T o = _head; 292 T n = (T) o.getNext(); 293 o.setNext(null); 294 295 if (null != n) { 296 n.setPrevious(null); 297 } 298 299 _head = n; 300 if (--_size == 0) { 301 _tail = null; 302 } 303 return o; 304 } 305 306 311 public T removeLast() { 312 T o = _tail; 313 T prev = (T) o.getPrevious(); 314 o.setPrevious(null); 315 316 if (null != prev) { 317 prev.setNext(null); 318 } 319 _tail = prev; 320 if (--_size == 0) { 321 _head = null; 322 } 323 return o; 324 } 325 326 332 protected void insert(int index, T linkable) { 333 T newLink = linkable; 334 335 if (_size == 0) { 336 _head = _tail = newLink; } else if (index == 0) { 338 newLink.setNext(_head); _head.setPrevious(newLink); 340 _head = newLink; 341 } else if (index == _size) { _tail.setNext(newLink); 343 newLink.setPrevious(_tail); 344 _tail = newLink; 345 } else { 346 T node = get(index); 347 348 T before = (T) node.getPrevious(); 349 if (before != null) before.setNext(linkable); 350 351 linkable.setPrevious(before); 352 linkable.setNext(node); 353 node.setPrevious(linkable); 354 } 355 _size++; 356 } 357 358 367 public boolean remove(Object o) { 368 if (o instanceof TLinkable) { 369 T p, n; 370 TLinkable link = (TLinkable)o; 371 372 p = (T) link.getPrevious(); 373 n = (T) link.getNext(); 374 375 if (n == null && p == null) { _head = _tail = null; 377 } else if (n == null) { link.setPrevious(null); 380 p.setNext(null); 381 _tail = p; 382 } else if (p == null) { link.setNext(null); 385 n.setPrevious(null); 386 _head = n; 387 } else { p.setNext(n); 389 n.setPrevious(p); 390 link.setNext(null); 391 link.setPrevious(null); 392 } 393 394 _size--; return true; 396 } else { 397 return false; 398 } 399 } 400 401 410 public void addBefore(T current, T newElement) { 411 if (current == _head) { 412 addFirst(newElement); 413 } else if (current == null) { 414 addLast(newElement); 415 } else { 416 TLinkable p = current.getPrevious(); 417 newElement.setNext(current); 418 p.setNext(newElement); 419 newElement.setPrevious(p); 420 current.setPrevious(newElement); 421 _size++; 422 } 423 } 424 425 426 public void writeExternal( ObjectOutput out ) throws IOException { 427 out.writeByte(0); 429 430 out.writeInt(_size); 432 433 out.writeObject(_head); 435 436 out.writeObject(_head); 438 } 439 440 public void readExternal( ObjectInput in ) 441 throws IOException, ClassNotFoundException { 442 443 in.readByte(); 445 446 _size = in.readInt(); 448 449 _head = (T) in.readObject(); 451 452 _tail = (T) in.readObject(); 454 } 455 456 457 461 protected final class IteratorImpl implements ListIterator <T> { 462 private int _nextIndex = 0; 463 private T _next; 464 private T _lastReturned; 465 466 472 IteratorImpl(int position) { 473 if (position < 0 || position > _size) { 474 throw new IndexOutOfBoundsException (); 475 } 476 477 _nextIndex = position; 478 if (position == 0) { 479 _next = _head; 480 } else if (position == _size) { 481 _next = null; 482 } else if (position < (_size >> 1)) { 483 int pos = 0; 484 for (_next = _head; pos < position; pos++) { 485 _next = (T) _next.getNext(); 486 } 487 } else { 488 int pos = _size - 1; 489 for (_next = _tail; pos > position; pos--) { 490 _next = (T) _next.getPrevious(); 491 } 492 } 493 } 494 495 501 public final void add(T linkable) { 502 _lastReturned = null; 503 _nextIndex++; 504 505 if (_size == 0) { 506 TLinkedList.this.add(linkable); 507 } else { 508 TLinkedList.this.addBefore(_next, linkable); 509 } 510 } 511 512 517 public final boolean hasNext() { 518 return _nextIndex != _size; 519 } 520 521 526 public final boolean hasPrevious() { 527 return _nextIndex != 0; 528 } 529 530 537 public final T next() { 538 if (_nextIndex == _size) { 539 throw new NoSuchElementException (); 540 } 541 542 _lastReturned = _next; 543 _next = (T) _next.getNext(); 544 _nextIndex++; 545 return _lastReturned; 546 } 547 548 554 public final int nextIndex() { 555 return _nextIndex; 556 } 557 558 565 public final T previous() { 566 if (_nextIndex == 0) { 567 throw new NoSuchElementException (); 568 } 569 570 if (_nextIndex == _size) { 571 _lastReturned = _next = _tail; 572 } else { 573 _lastReturned = _next = (T) _next.getPrevious(); 574 } 575 576 _nextIndex--; 577 return _lastReturned; 578 } 579 580 585 public final int previousIndex() { 586 return _nextIndex - 1; 587 } 588 589 597 public final void remove() { 598 if (_lastReturned == null) { 599 throw new IllegalStateException ("must invoke next or previous before invoking remove"); 600 } 601 602 if (_lastReturned != _next) { 603 _nextIndex--; 604 } 605 _next = (T) _lastReturned.getNext(); 606 TLinkedList.this.remove(_lastReturned); 607 _lastReturned = null; 608 } 609 610 616 public final void set(T linkable) { 617 if (_lastReturned == null) { 618 throw new IllegalStateException (); 619 } 620 T l = linkable; 621 622 if (_lastReturned == _head) { 625 _head = l; 626 } 627 628 if (_lastReturned == _tail) { 629 _tail = l; 630 } 631 632 swap(_lastReturned, l); 633 _lastReturned = l; 634 } 635 636 642 private void swap(T from, T to) { 643 T p = (T) from.getPrevious(); 644 T n = (T) from.getNext(); 645 646 if (null != p) { 647 to.setPrevious(p); 648 p.setNext(to); 649 } 650 if (null != n) { 651 to.setNext(n); 652 n.setPrevious(to); 653 } 654 from.setNext(null); 655 from.setPrevious(null); 656 } 657 } 658 } | Popular Tags |