1 package org.ozoneDB.collections; 2 3 39 40 import java.io.ObjectOutputStream ; 41 import java.io.ObjectInputStream ; 42 import java.io.IOException ; 43 import java.lang.reflect.Array ; 44 import java.util.*; 45 46 74 public class FullLinkedListImpl extends BaseListImpl implements FullLinkedList { 75 76 79 private transient Entry first; 80 81 84 private transient Entry last; 85 86 89 private transient int size = 0; 90 91 94 private static final class Entry { 95 96 Object data; 97 98 99 Entry next; 100 101 102 Entry previous; 103 104 108 Entry(Object data) { 109 this.data = data; 110 } 111 } 113 125 Entry getEntry(int n) { 127 Entry e; 128 if (n < size / 2) { 129 e = first; 130 while (n-- > 0) { 132 e = e.next; 133 } 134 } 135 else { 136 e = last; 137 while (++n < size) { 139 e = e.previous; 140 } 141 } 142 return e; 143 } 144 145 151 void removeEntry(Entry e) { 153 modCount++; 154 size--; 155 if (size == 0) { 156 first = last = null; 157 } else { 158 if (e == first) { 159 first = e.next; 160 e.next.previous = null; 161 } else if (e == last) { 162 last = e.previous; 163 e.previous.next = null; 164 } else { 165 e.next.previous = e.previous; 166 e.previous.next = e.next; 167 } 168 } 169 } 170 171 177 private void checkBoundsInclusive(int index) { 178 if (index < 0 || index > size) 179 throw new IndexOutOfBoundsException ("Index: " + index + ", Size:" 180 + size); 181 } 182 183 189 private void checkBoundsExclusive(int index) { 190 if (index < 0 || index >= size) 191 throw new IndexOutOfBoundsException ("Index: " + index + ", Size:" 192 + size); 193 } 194 195 198 public FullLinkedListImpl() { 199 } 200 201 208 public FullLinkedListImpl(Collection c) { 209 addAll(c); 210 } 211 212 218 public Object getFirst() { 219 if (size == 0) 220 throw new NoSuchElementException(); 221 return first.data; 222 } 223 224 230 public Object getLast() { 231 if (size == 0) 232 throw new NoSuchElementException(); 233 return last.data; 234 } 235 236 242 public Object removeFirst() { 243 if (size == 0) 244 throw new NoSuchElementException(); 245 modCount++; 246 size--; 247 Object r = first.data; 248 249 if (first.next != null) 250 first.next.previous = null; 251 else 252 last = null; 253 254 first = first.next; 255 256 return r; 257 } 258 259 265 public Object removeLast() { 266 if (size == 0) 267 throw new NoSuchElementException(); 268 modCount++; 269 size--; 270 Object r = last.data; 271 272 if (last.previous != null) 273 last.previous.next = null; 274 else 275 first = null; 276 277 last = last.previous; 278 279 return r; 280 } 281 282 287 public void addFirst(Object o) { 288 Entry e = new Entry(o); 289 290 modCount++; 291 if (size == 0) 292 first = last = e; 293 else { 294 e.next = first; 295 first.previous = e; 296 first = e; 297 } 298 size++; 299 } 300 301 306 public void addLast(Object o) { 307 addLastEntry(new Entry(o)); 308 } 309 310 315 private void addLastEntry(Entry e) { 316 modCount++; 317 if (size == 0) 318 first = last = e; 319 else { 320 e.previous = last; 321 last.next = e; 322 last = e; 323 } 324 size++; 325 } 326 327 334 public boolean contains(Object o) { 335 Entry e = first; 336 while (e != null) { 337 if (equals(o, e.data)) 338 return true; 339 e = e.next; 340 } 341 return false; 342 } 343 344 349 public int size() { 350 return size; 351 } 352 353 359 public boolean add(Object o) { 360 addLastEntry(new Entry(o)); 361 return true; 362 } 363 364 371 public boolean remove(Object o) { 372 Entry e = first; 373 while (e != null) { 374 if (equals(o, e.data)) { 375 removeEntry(e); 376 return true; 377 } 378 e = e.next; 379 } 380 return false; 381 } 382 383 392 public boolean addAll(Collection c) { 393 return addAll(size, c); 394 } 395 396 406 public boolean addAll(int index, Collection c) { 407 checkBoundsInclusive(index); 408 int csize = c.size(); 409 410 if (csize == 0) 411 return false; 412 413 Iterator itr = c.iterator(); 414 415 Entry after = null; 419 Entry before = null; 420 if (index != size) { 421 after = getEntry(index); 422 before = after.previous; 423 } 424 else 425 before = last; 426 427 Entry e = new Entry(itr.next()); 432 e.previous = before; 433 Entry prev = e; 434 Entry firstNew = e; 435 436 for (int pos = 1; pos < csize; pos++) { 438 e = new Entry(itr.next()); 439 e.previous = prev; 440 prev.next = e; 441 prev = e; 442 } 443 444 modCount++; 446 size += csize; 447 prev.next = after; 448 if (after != null) 449 after.previous = e; 450 else 451 last = e; 452 453 if (before != null) 454 before.next = firstNew; 455 else 456 first = firstNew; 457 return true; 458 } 459 460 463 public void clear() { 464 if (size > 0) { 465 modCount++; 466 first = null; 467 last = null; 468 size = 0; 469 } 470 } 471 472 479 public Object get(int index) { 480 checkBoundsExclusive(index); 481 return getEntry(index).data; 482 } 483 484 492 public Object set(int index, Object o) { 493 checkBoundsExclusive(index); 494 Entry e = getEntry(index); 495 Object old = e.data; 496 e.data = o; 497 return old; 498 } 499 500 507 public void add(int index, Object o) { 508 checkBoundsInclusive(index); 509 Entry e = new Entry(o); 510 511 if (index < size) { 512 modCount++; 513 Entry after = getEntry(index); 514 e.next = after; 515 e.previous = after.previous; 516 if (after.previous == null) 517 first = e; 518 else 519 after.previous.next = e; 520 after.previous = e; 521 size++; 522 } 523 else 524 addLastEntry(e); 525 } 526 527 534 public Object remove(int index) { 535 checkBoundsExclusive(index); 536 Entry e = getEntry(index); 537 removeEntry(e); 538 return e.data; 539 } 540 541 547 public int indexOf(Object o) { 548 int index = 0; 549 Entry e = first; 550 while (e != null) { 551 if (equals(o, e.data)) 552 return index; 553 index++; 554 e = e.next; 555 } 556 return -1; 557 } 558 559 565 public int lastIndexOf(Object o) { 566 int index = size - 1; 567 Entry e = last; 568 while (e != null) { 569 if (equals(o, e.data)) 570 return index; 571 index--; 572 e = e.previous; 573 } 574 return -1; 575 } 576 577 public Iterator _org_ozoneDB_internalIterator() { 578 throw new RuntimeException ("Not yet implemented"); 579 } 580 581 590 public ListIterator listIterator(int index) { 591 checkBoundsInclusive(index); 592 return new LinkedListItr(index); 593 } 594 595 601 public Object clone() { 602 LinkedList copy = null; 603 try { 604 copy = (LinkedList) super.clone(); 605 } 606 catch (CloneNotSupportedException ex) { 607 } 608 copy.clear(); 609 copy.addAll(this); 610 return copy; 611 } 612 613 618 public Object [] toArray() { 619 Object [] array = new Object [size]; 620 Entry e = first; 621 for (int i = 0; i < size; i++) { 622 array[i] = e.data; 623 e = e.next; 624 } 625 return array; 626 } 627 628 642 public Object [] toArray(Object [] a) { 643 if (a.length < size) 644 a = (Object []) Array.newInstance(a.getClass().getComponentType(), size); 645 else if (a.length > size) 646 a[size] = null; 647 Entry e = first; 648 for (int i = 0; i < size; i++) { 649 a[i] = e.data; 650 e = e.next; 651 } 652 return a; 653 } 654 655 public int _org_ozoneDB_getModCount() { 656 throw new RuntimeException ("Not yet Implemented"); 657 } 658 659 public List _org_ozoneDB_emptyClientCollection() { 660 throw new RuntimeException ("Not yet Implemented"); 661 } 662 663 671 private void writeObject(ObjectOutputStream s) throws IOException { 672 s.defaultWriteObject(); 673 s.writeInt(size); 674 Entry e = first; 675 while (e != null) { 676 s.writeObject(e.data); 677 e = e.next; 678 } 679 } 680 681 690 private void readObject(ObjectInputStream s) 691 throws IOException , ClassNotFoundException { 692 s.defaultReadObject(); 693 int i = s.readInt(); 694 while (--i >= 0) 695 addLastEntry(new Entry(s.readObject())); 696 } 697 698 705 private final class LinkedListItr implements ListIterator { 706 707 private int knownMod = modCount; 708 709 710 private Entry next; 711 712 713 private Entry previous; 714 715 716 private Entry lastReturned; 717 718 719 private int position; 720 721 726 LinkedListItr(int index) { 727 if (index == size) { 728 next = null; 729 previous = last; 730 } 731 else { 732 next = getEntry(index); 733 previous = next.previous; 734 } 735 position = index; 736 } 737 738 743 private void checkMod() { 744 if (knownMod != modCount) 745 throw new ConcurrentModificationException(); 746 } 747 748 754 public int nextIndex() { 755 checkMod(); 756 return position; 757 } 758 759 765 public int previousIndex() { 766 checkMod(); 767 return position - 1; 768 } 769 770 776 public boolean hasNext() { 777 checkMod(); 778 return (next != null); 779 } 780 781 787 public boolean hasPrevious() { 788 checkMod(); 789 return (previous != null); 790 } 791 792 799 public Object next() { 800 checkMod(); 801 if (next == null) 802 throw new NoSuchElementException(); 803 position++; 804 lastReturned = previous = next; 805 next = lastReturned.next; 806 return lastReturned.data; 807 } 808 809 816 public Object previous() { 817 checkMod(); 818 if (previous == null) 819 throw new NoSuchElementException(); 820 position--; 821 lastReturned = next = previous; 822 previous = lastReturned.previous; 823 return lastReturned.data; 824 } 825 826 832 public void remove() { 833 checkMod(); 834 if (lastReturned == null) 835 throw new IllegalStateException (); 836 837 if (lastReturned == previous) 840 position--; 841 842 next = lastReturned.next; 843 previous = lastReturned.previous; 844 removeEntry(lastReturned); 845 knownMod++; 846 847 lastReturned = null; 848 } 849 850 856 public void add(Object o) { 857 checkMod(); 858 modCount++; 859 knownMod++; 860 size++; 861 position++; 862 Entry e = new Entry(o); 863 e.previous = previous; 864 e.next = next; 865 866 if (previous != null) 867 previous.next = e; 868 else 869 first = e; 870 871 if (next != null) 872 next.previous = e; 873 else 874 last = e; 875 876 previous = e; 877 lastReturned = null; 878 } 879 880 887 public void set(Object o) { 888 checkMod(); 889 if (lastReturned == null) 890 throw new IllegalStateException (); 891 lastReturned.data = o; 892 } 893 } 895 } 896 | Popular Tags |