1 #import "LinkedList.h" 2 #import <Foundation/Foundation.h> 3 #import "AMutableArray.h" 4 #import "RuntimeException.h" 5 6 @implementation LLNode 7 8 @synthesize next; 9 @synthesize prev; 10 @synthesize item; 11 12 + (LLNode *) newNode:(LLNode *)aPrev element:(id)anElement next:(LLNode *)aNext 13 { 14 return [[LLNode alloc] init:aPrev element:anElement next:aNext]; 15 } 16 17 - (id) init:(LLNode *)aPrev element:(id)anElement next:(LLNode *)aNext 18 { 19 self = [super init]; 20 if (self) { 21 item = anElement; 22 next = aNext; 23 prev = aPrev; 24 } 25 return self; 26 } 27 28 - (void) dealloc 29 { 30 [item release]; 31 [next release]; 32 [prev release]; 33 [super dealloc]; 34 } 35 36 @end 37 38 @implementation ListIterator 39 40 + (ListIterator *) newIterator:(LinkedList *)anLL 41 { 42 return [[ListIterator alloc] init:anLL withIndex:0]; 43 } 44 45 + (ListIterator *) newIterator:(LinkedList *)anLL withIndex:(NSInteger)anIndex 46 { 47 return [[ListIterator alloc] init:anLL withIndex:anIndex]; 48 } 49 50 - (id) init:(LinkedList *)anLL withIndex:(NSInteger)anIndex 51 { 52 self = [super init]; 53 if ( self ) { 54 ll = anLL; 55 index = anIndex; 56 lastReturned = nil; 57 expectedModCount = ll.modCount; 58 next = (index == count) ? nil : [ll node:anIndex]; 59 nextIndex = index; 60 } 61 return self; 62 } 63 64 - (BOOL) hasNext 65 { 66 return nextIndex < count; 67 } 68 69 - (id) next 70 { 71 [self checkForComodification]; 72 if (![self hasNext]) 73 @throw [[[NoSuchElementException alloc] init] autorelease]; 74 lastReturned = next; 75 next = next.next; 76 nextIndex++; 77 return lastReturned.item; 78 } 79 80 - (BOOL) hasPrevious 81 { 82 return nextIndex > 0; 83 } 84 85 - (id) previous 86 { 87 [self checkForComodification]; 88 if (![self hasPrevious]) 89 @throw [[[NoSuchElementException alloc] init] autorelease]; 90 lastReturned = next = (next == nil) ? ll.last : next.prev; 91 nextIndex--; 92 return lastReturned.item; 93 } 94 95 - (NSInteger) nextIndex 96 { 97 return nextIndex; 98 } 99 100 - (NSInteger) previousIndex 101 { 102 return nextIndex - 1; 103 } 104 105 - (void) remove 106 { 107 [self checkForComodification]; 108 if (lastReturned == nil) 109 @throw [[[IllegalStateException alloc] init] autorelease]; 110 LLNode *lastNext = lastReturned.next; 111 [ll unlink:lastReturned]; 112 if (next == lastReturned) 113 next = lastNext; 114 else 115 nextIndex--; 116 lastReturned = nil; 117 expectedModCount++; 118 } 119 120 - (void) set:(id)e 121 { 122 if (lastReturned == nil) 123 @throw [[[IllegalStateException alloc] init] autorelease]; 124 [self checkForComodification]; 125 lastReturned.item = e; 126 } 127 128 - (void) add:(id)e 129 { 130 [self checkForComodification]; 131 lastReturned = nil; 132 if (next == nil) 133 [ll linkLast:e]; 134 else 135 [ll linkBefore:e succ:next]; 136 nextIndex++; 137 expectedModCount++; 138 } 139 140 - (void) checkForComodification 141 { 142 if (ll.modCount != expectedModCount) 143 @throw [[[ConcurrentModificationException alloc] init] autorelease]; 144 } 145 146 - (void) dealloc 147 { 148 [lastReturned release]; 149 [next release]; 150 [super dealloc]; 151 } 152 153 @end 154 155 @implementation DescendingIterator 156 157 + (DescendingIterator *)newIterator:(LinkedList *)anLL 158 { 159 return [[DescendingIterator alloc] init:anLL]; 160 } 161 162 - (id) init:(LinkedList *)anLL 163 { 164 self = [super init:anLL withIndex:[anLL count]]; 165 if ( self ) { 166 167 } 168 return self; 169 } 170 171 - (BOOL) hasNext 172 { 173 return [self hasPrevious]; 174 } 175 176 - (id) next 177 { 178 return [self previous]; 179 } 180 181 - (void) remove 182 { 183 [self remove]; 184 } 185 186 - (void) dealloc 187 { 188 [super dealloc]; 189 } 190 191 @end 192 193 //long const serialVersionUID = 876323262645176354L; 194 195 @implementation LinkedList 196 197 @synthesize first; 198 @synthesize last; 199 @synthesize count; 200 @synthesize modCount; 201 202 + (LinkedList *)newLinkedList 203 { 204 return [[LinkedList alloc] init]; 205 } 206 207 + (LinkedList *)newLinkedList:(NSArray *)c 208 { 209 return [[LinkedList alloc] initWithC:c]; 210 } 211 212 /** 213 * Constructs an empty list. 214 */ 215 - (id) init 216 { 217 self = [super init]; 218 if ( self ) { 219 count = 0; 220 } 221 return self; 222 } 223 224 225 /** 226 * Constructs a list containing the elements of the specified 227 * collection, in the order they are returned by the collection's 228 * iterator. 229 * 230 * @param c the collection whose elements are to be placed into this list 231 * @throws NullPointerException if the specified collection is null 232 */ 233 - (id) initWithC:(NSArray *)c 234 { 235 self = [super init]; 236 if ( self ) { 237 count = 0; 238 [self addAll:c]; 239 } 240 return self; 241 } 242 243 244 - (void) dealloc 245 { 246 [first release]; 247 [last release]; 248 [super dealloc]; 249 } 250 251 /** 252 * Links e as first element. 253 */ 254 - (void) linkFirst:(id)e 255 { 256 LLNode *f = first; 257 LLNode *newNode = [[LLNode newNode:nil element:e next:f] autorelease]; 258 first = newNode; 259 if (f == nil) 260 last = newNode; 261 else 262 f.prev = newNode; 263 count++; 264 modCount++; 265 } 266 267 268 /** 269 * Links e as last element. 270 */ 271 - (void) linkLast:(id)e 272 { 273 LLNode *l = last; 274 LLNode *newNode = [[LLNode newNode:l element:e next:nil] autorelease]; 275 last = newNode; 276 if (l == nil) 277 first = newNode; 278 else 279 l.next = newNode; 280 count++; 281 modCount++; 282 } 283 284 285 /** 286 * Inserts element e before non-null LLNode succ. 287 */ 288 - (void) linkBefore:(id)e succ:(LLNode *)succ 289 { 290 LLNode *pred = succ.prev; 291 LLNode *newNode = [[LLNode newNode:pred element:e next:succ] autorelease]; 292 succ.prev = newNode; 293 if (pred == nil) 294 first = newNode; 295 else 296 pred.next = newNode; 297 count++; 298 modCount++; 299 } 300 301 302 /** 303 * Unlinks non-null first node f. 304 */ 305 - (id) unlinkFirst:(LLNode *)f 306 { 307 id element = f.item; 308 LLNode *next = f.next; 309 f.item = nil; 310 f.next = nil; 311 first = next; 312 if (next == nil) 313 last = nil; 314 else 315 next.prev = nil; 316 count--; 317 modCount++; 318 return element; 319 } 320 321 322 /** 323 * Unlinks non-null last node l. 324 */ 325 - (id) unlinkLast:(LLNode *)l 326 { 327 id element = l.item; 328 LLNode *prev = l.prev; 329 l.item = nil; 330 l.prev = nil; 331 last = prev; 332 if (prev == nil) 333 first = nil; 334 else 335 prev.next = nil; 336 count--; 337 modCount++; 338 return element; 339 } 340 341 342 /** 343 * Unlinks non-null node x. 344 */ 345 - (LLNode *) unlink:(LLNode *)x 346 { 347 id element = x.item; 348 LLNode *next = x.next; 349 LLNode *prev = x.prev; 350 if (prev == nil) { 351 first = next; 352 } 353 else { 354 prev.next = next; 355 x.prev = nil; 356 } 357 if (next == nil) { 358 last = prev; 359 } 360 else { 361 next.prev = prev; 362 x.next = nil; 363 } 364 x.item = nil; 365 count--; 366 modCount++; 367 return element; 368 } 369 370 371 /** 372 * Returns the first element in this list. 373 * 374 * @return the first element in this list 375 * @throws NoSuchElementException if this list is empty 376 */ 377 - (LLNode *) first 378 { 379 LLNode *f = first; 380 if (f == nil) 381 @throw [[[NoSuchElementException alloc] init] autorelease]; 382 return f.item; 383 } 384 385 386 /** 387 * Returns the last element in this list. 388 * 389 * @return the last element in this list 390 * @throws NoSuchElementException if this list is empty 391 */ 392 - (LLNode *) last 393 { 394 LLNode *l = last; 395 if (l == nil) 396 @throw [[[NoSuchElementException alloc] init] autorelease]; 397 return l.item; 398 } 399 400 401 /** 402 * Removes and returns the first element from this list. 403 * 404 * @return the first element from this list 405 * @throws NoSuchElementException if this list is empty 406 */ 407 - (LLNode *) removeFirst 408 { 409 LLNode *f = first; 410 if (f == nil) 411 @throw [[[NoSuchElementException alloc] init] autorelease]; 412 return [self unlinkFirst:f]; 413 } 414 415 416 /** 417 * Removes and returns the last element from this list. 418 * 419 * @return the last element from this list 420 * @throws NoSuchElementException if this list is empty 421 */ 422 - (LLNode *) removeLast 423 { 424 LLNode *l = last; 425 if (l == nil) 426 @throw [[[NoSuchElementException alloc] init] autorelease]; 427 return [self unlinkLast:l]; 428 } 429 430 431 /** 432 * Inserts the specified element at the beginning of this list. 433 * 434 * @param e the element to add 435 */ 436 - (void) addFirst:(LLNode *)e 437 { 438 [self linkFirst:e]; 439 } 440 441 442 /** 443 * Appends the specified element to the end of this list. 444 * 445 * <p>This method is equivalent to {@link #add}. 446 * 447 * @param e the element to add 448 */ 449 - (void) addLast:(LLNode *)e 450 { 451 [self linkLast:e]; 452 } 453 454 455 /** 456 * Returns {@code true} if this list contains the specified element. 457 * More formally, returns {@code true} if and only if this list contains 458 * at least one element {@code e} such that 459 * <tt>(o==null ? e==null : o.equals(e))</tt>. 460 * 461 * @param o element whose presence in this list is to be tested 462 * @return {@code true} if this list contains the specified element 463 */ 464 - (BOOL) contains:(id)o 465 { 466 return [self indexOf:o] != -1; 467 } 468 469 470 /** 471 * Returns the number of elements in this list. 472 * 473 * @return the number of elements in this list 474 */ 475 - (NSInteger) count 476 { 477 return count; 478 } 479 480 481 /** 482 * Appends the specified element to the end of this list. 483 * 484 * <p>This method is equivalent to {@link #addLast}. 485 * 486 * @param e element to be appended to this list 487 * @return {@code true} (as specified by {@link Collection#add}) 488 */ 489 - (BOOL) add:(LLNode *)e 490 { 491 [self linkLast:e]; 492 return YES; 493 } 494 495 496 /** 497 * Removes the first occurrence of the specified element from this list, 498 * if it is present. If this list does not contain the element, it is 499 * unchanged. More formally, removes the element with the lowest index 500 * {@code i} such that 501 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> 502 * (if such an element exists). Returns {@code true} if this list 503 * contained the specified element (or equivalently, if this list 504 * changed as a result of the call). 505 * 506 * @param o element to be removed from this list, if present 507 * @return {@code true} if this list contained the specified element 508 */ 509 - (BOOL) remove:(id)o 510 { 511 if (o == nil) { 512 513 for (LLNode *x = first; x != nil; x = x.next) { 514 if (x.item == nil) { 515 [self unlink:x]; 516 return YES; 517 } 518 } 519 520 } 521 else { 522 523 for (LLNode *x = first; x != nil; x = x.next) { 524 if ([o isEqualTo:x.item]) { 525 [self unlink:x]; 526 return YES; 527 } 528 } 529 530 } 531 return NO; 532 } 533 534 535 /** 536 * Appends all of the elements in the specified collection to the end of 537 * this list, in the order that they are returned by the specified 538 * collection's iterator. The behavior of this operation is undefined if 539 * the specified collection is modified while the operation is in 540 * progress. (Note that this will occur if the specified collection is 541 * this list, and it's nonempty.) 542 * 543 * @param c collection containing elements to be added to this list 544 * @return {@code true} if this list changed as a result of the call 545 * @throws NullPointerException if the specified collection is null 546 */ 547 - (BOOL) addAll:(NSArray *)c 548 { 549 return [self addAll:count c:c]; 550 } 551 552 553 /** 554 * Inserts all of the elements in the specified collection into this 555 * list, starting at the specified position. Shifts the element 556 * currently at that position (if any) and any subsequent elements to 557 * the right (increases their indices). The new elements will appear 558 * in the list in the order that they are returned by the 559 * specified collection's iterator. 560 * 561 * @param index index at which to insert the first element 562 * from the specified collection 563 * @param c collection containing elements to be added to this list 564 * @return {@code true} if this list changed as a result of the call 565 * @throws IndexOutOfBoundsException {@inheritDoc} 566 * @throws NullPointerException if the specified collection is null 567 */ 568 - (BOOL) addAll:(NSInteger)index c:(NSArray *)c 569 { 570 [self checkPositionIndex:index]; 571 AMutableArray *a = [AMutableArray arrayWithArray:c]; 572 NSInteger numNew = [a count]; 573 if (numNew == 0) 574 return NO; 575 LLNode *pred, *succ; 576 if (index == count) { 577 succ = nil; 578 pred = last; 579 } 580 else { 581 succ = [self node:index]; 582 pred = succ.prev; 583 } 584 585 for (id o in a) { 586 id e = (id)o; 587 LLNode *newNode = [[LLNode newNode:pred element:e next:nil] autorelease]; 588 if (pred == nil) 589 first = newNode; 590 else 591 pred.next = newNode; 592 pred = newNode; 593 } 594 595 if (succ == nil) { 596 last = pred; 597 } 598 else { 599 pred.next = succ; 600 succ.prev = pred; 601 } 602 count += numNew; 603 modCount++; 604 return YES; 605 } 606 607 608 /** 609 * Removes all of the elements from this list. 610 * The list will be empty after this call returns. 611 */ 612 - (void) clear 613 { 614 615 for (LLNode *x = first; x != nil; ) { 616 LLNode *next = x.next; 617 x.item = nil; 618 x.next = nil; 619 x.prev = nil; 620 x = next; 621 } 622 623 first = last = nil; 624 count = 0; 625 modCount++; 626 } 627 628 629 /** 630 * Returns the element at the specified position in this list. 631 * 632 * @param index index of the element to return 633 * @return the element at the specified position in this list 634 * @throws IndexOutOfBoundsException {@inheritDoc} 635 */ 636 - (id) get:(NSInteger)index 637 { 638 [self checkElementIndex:index]; 639 return [self node:index].item; 640 } 641 642 643 /** 644 * Replaces the element at the specified position in this list with the 645 * specified element. 646 * 647 * @param index index of the element to replace 648 * @param element element to be stored at the specified position 649 * @return the element previously at the specified position 650 * @throws IndexOutOfBoundsException {@inheritDoc} 651 */ 652 - (id) set:(NSInteger)index element:(id)element 653 { 654 [self checkElementIndex:index]; 655 LLNode *x = [self node:index]; 656 id oldVal = x.item; 657 x.item = element; 658 return oldVal; 659 } 660 661 662 /** 663 * Inserts the specified element at the specified position in this list. 664 * Shifts the element currently at that position (if any) and any 665 * subsequent elements to the right (adds one to their indices). 666 * 667 * @param index index at which the specified element is to be inserted 668 * @param element element to be inserted 669 * @throws IndexOutOfBoundsException {@inheritDoc} 670 */ 671 - (void) add:(NSInteger)index element:(LLNode *)element 672 { 673 [self checkPositionIndex:index]; 674 if (index == count) 675 [self linkLast:element]; 676 else 677 [self linkBefore:element succ:[self node:index]]; 678 } 679 680 681 /** 682 * Removes the element at the specified position in this list. Shifts any 683 * subsequent elements to the left (subtracts one from their indices). 684 * Returns the element that was removed from the list. 685 * 686 * @param index the index of the element to be removed 687 * @return the element previously at the specified position 688 * @throws IndexOutOfBoundsException {@inheritDoc} 689 */ 690 - (LLNode *) removeIdx:(NSInteger)index 691 { 692 [self checkElementIndex:index]; 693 return [self unlink:[self node:index]]; 694 } 695 696 697 /** 698 * Tells if the argument is the index of an existing element. 699 */ 700 - (BOOL) isElementIndex:(NSInteger)index 701 { 702 return index >= 0 && index < count; 703 } 704 705 706 /** 707 * Tells if the argument is the index of a valid position for an 708 * iterator or an add operation. 709 */ 710 - (BOOL) isPositionIndex:(NSInteger)index 711 { 712 return index >= 0 && index <= count; 713 } 714 715 716 /** 717 * Constructs an IndexOutOfBoundsException detail message. 718 * Of the many possible refactorings of the error handling code, 719 * this "outlining" performs best with both server and client VMs. 720 */ 721 - (NSString *) outOfBoundsMsg:(NSInteger)index 722 { 723 return [NSString stringWithFormat:@"Index: %d, Size: %d", index, count]; 724 } 725 726 - (void) checkElementIndex:(NSInteger)index 727 { 728 if (![self isElementIndex:index]) 729 @throw [[IndexOutOfBoundsException newException:[self outOfBoundsMsg:index]] autorelease]; 730 } 731 732 - (void) checkPositionIndex:(NSInteger)index 733 { 734 if (![self isPositionIndex:index]) 735 @throw [[IndexOutOfBoundsException newException:[self outOfBoundsMsg:index]] autorelease]; 736 } 737 738 739 /** 740 * Returns the (non-null) LLNode at the specified element index. 741 */ 742 - (LLNode *) node:(NSInteger)index 743 { 744 if (index < (count >> 1)) { 745 LLNode *x = first; 746 747 for (NSInteger i = 0; i < index; i++) 748 x = x.next; 749 750 return x; 751 } 752 else { 753 LLNode *x = last; 754 755 for (NSInteger i = count - 1; i > index; i--) 756 x = x.prev; 757 758 return x; 759 } 760 } 761 762 763 /** 764 * Returns the index of the first occurrence of the specified element 765 * in this list, or -1 if this list does not contain the element. 766 * More formally, returns the lowest index {@code i} such that 767 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, 768 * or -1 if there is no such index. 769 * 770 * @param o element to search for 771 * @return the index of the first occurrence of the specified element in 772 * this list, or -1 if this list does not contain the element 773 */ 774 - (NSInteger) indexOf:(id)o 775 { 776 NSInteger index = 0; 777 if (o == nil) { 778 779 for (LLNode *x = first; x != nil; x = x.next) { 780 if (x.item == nil) 781 return index; 782 index++; 783 } 784 785 } 786 else { 787 788 for (LLNode *x = first; x != nil; x = x.next) { 789 if ([o isEqualTo:x.item]) 790 return index; 791 index++; 792 } 793 794 } 795 return -1; 796 } 797 798 799 /** 800 * Returns the index of the last occurrence of the specified element 801 * in this list, or -1 if this list does not contain the element. 802 * More formally, returns the highest index {@code i} such that 803 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, 804 * or -1 if there is no such index. 805 * 806 * @param o element to search for 807 * @return the index of the last occurrence of the specified element in 808 * this list, or -1 if this list does not contain the element 809 */ 810 - (NSInteger) lastIndexOf:(id)o 811 { 812 NSInteger index = count; 813 if (o == nil) { 814 815 for (LLNode *x = last; x != nil; x = x.prev) { 816 index--; 817 if (x.item == nil) 818 return index; 819 } 820 821 } 822 else { 823 824 for (LLNode *x = last; x != nil; x = x.prev) { 825 index--; 826 if ([o isEqualTo:x.item]) 827 return index; 828 } 829 830 } 831 return -1; 832 } 833 834 835 /** 836 * Retrieves, but does not remove, the head (first element) of this list. 837 * 838 * @return the head of this list, or {@code null} if this list is empty 839 * @since 1.5 840 */ 841 - (LLNode *) peek 842 { 843 LLNode *f = first; 844 return (f == nil) ? nil : f.item; 845 } 846 847 848 /** 849 * Retrieves, but does not remove, the head (first element) of this list. 850 * 851 * @return the head of this list 852 * @throws NoSuchElementException if this list is empty 853 * @since 1.5 854 */ 855 - (LLNode *) element 856 { 857 return [self first]; 858 } 859 860 861 /** 862 * Retrieves and removes the head (first element) of this list. 863 * 864 * @return the head of this list, or {@code null} if this list is empty 865 * @since 1.5 866 */ 867 - (LLNode *) poll 868 { 869 LLNode *f = first; 870 return (f == nil) ? nil : [self unlinkFirst:f]; 871 } 872 873 874 /** 875 * Retrieves and removes the head (first element) of this list. 876 * 877 * @return the head of this list 878 * @throws NoSuchElementException if this list is empty 879 * @since 1.5 880 */ 881 - (LLNode *) remove 882 { 883 return [self removeFirst]; 884 } 885 886 887 /** 888 * Adds the specified element as the tail (last element) of this list. 889 * 890 * @param e the element to add 891 * @return {@code true} (as specified by {@link Queue#offer}) 892 * @since 1.5 893 */ 894 - (BOOL) offer:(LLNode *)e 895 { 896 return [self add:e]; 897 } 898 899 900 /** 901 * Inserts the specified element at the front of this list. 902 * 903 * @param e the element to insert 904 * @return {@code true} (as specified by {@link Deque#offerFirst}) 905 * @since 1.6 906 */ 907 - (BOOL) offerFirst:(LLNode *)e 908 { 909 [self addFirst:e]; 910 return YES; 911 } 912 913 914 /** 915 * Inserts the specified element at the end of this list. 916 * 917 * @param e the element to insert 918 * @return {@code true} (as specified by {@link Deque#offerLast}) 919 * @since 1.6 920 */ 921 - (BOOL) offerLast:(LLNode *)e 922 { 923 [self addLast:e]; 924 return YES; 925 } 926 927 928 /** 929 * Retrieves, but does not remove, the first element of this list, 930 * or returns {@code null} if this list is empty. 931 * 932 * @return the first element of this list, or {@code null} 933 * if this list is empty 934 * @since 1.6 935 */ 936 - (LLNode *) peekFirst 937 { 938 LLNode *f = first; 939 return (f == nil) ? nil : f.item; 940 } 941 942 943 /** 944 * Retrieves, but does not remove, the last element of this list, 945 * or returns {@code null} if this list is empty. 946 * 947 * @return the last element of this list, or {@code null} 948 * if this list is empty 949 * @since 1.6 950 */ 951 - (LLNode *) peekLast 952 { 953 LLNode *l = last; 954 return (l == nil) ? nil : l.item; 955 } 956 957 958 /** 959 * Retrieves and removes the first element of this list, 960 * or returns {@code null} if this list is empty. 961 * 962 * @return the first element of this list, or {@code null} if 963 * this list is empty 964 * @since 1.6 965 */ 966 - (LLNode *) pollFirst 967 { 968 LLNode *f = first; 969 return (f == nil) ? nil : [self unlinkFirst:f]; 970 } 971 972 973 /** 974 * Retrieves and removes the last element of this list, 975 * or returns {@code null} if this list is empty. 976 * 977 * @return the last element of this list, or {@code null} if 978 * this list is empty 979 * @since 1.6 980 */ 981 - (LLNode *) pollLast 982 { 983 LLNode *l = last; 984 return (l == nil) ? nil : [self unlinkLast:l]; 985 } 986 987 988 /** 989 * Pushes an element onto the stack represented by this list. In other 990 * words, inserts the element at the front of this list. 991 * 992 * <p>This method is equivalent to {@link #addFirst}. 993 * 994 * @param e the element to push 995 * @since 1.6 996 */ 997 - (void) push:(LLNode *)e 998 { 999 [self addFirst:e]; 1000 } 1001 1002 1003 /** 1004 * Pops an element from the stack represented by this list. In other 1005 * words, removes and returns the first element of this list. 1006 * 1007 * <p>This method is equivalent to {@link #removeFirst()}. 1008 * 1009 * @return the element at the front of this list (which is the top 1010 * of the stack represented by this list) 1011 * @throws NoSuchElementException if this list is empty 1012 * @since 1.6 1013 */ 1014 - (LLNode *) pop 1015 { 1016 return [self removeFirst]; 1017 } 1018 1019 1020 /** 1021 * Removes the first occurrence of the specified element in this 1022 * list (when traversing the list from head to tail). If the list 1023 * does not contain the element, it is unchanged. 1024 * 1025 * @param o element to be removed from this list, if present 1026 * @return {@code true} if the list contained the specified element 1027 * @since 1.6 1028 */ 1029 - (BOOL) removeFirstOccurrence:(id)o 1030 { 1031 return [self remove:o]; 1032 } 1033 1034 1035 /** 1036 * Removes the last occurrence of the specified element in this 1037 * list (when traversing the list from head to tail). If the list 1038 * does not contain the element, it is unchanged. 1039 * 1040 * @param o element to be removed from this list, if present 1041 * @return {@code true} if the list contained the specified element 1042 * @since 1.6 1043 */ 1044 - (BOOL) removeLastOccurrence:(id)o 1045 { 1046 if (o == nil) { 1047 1048 for (LLNode *x = last; x != nil; x = x.prev) { 1049 if (x.item == nil) { 1050 [self unlink:x]; 1051 return YES; 1052 } 1053 } 1054 1055 } 1056 else { 1057 1058 for (LLNode *x = last; x != nil; x = x.prev) { 1059 if ([o isEqualTo:x.item]) { 1060 [self unlink:x]; 1061 return YES; 1062 } 1063 } 1064 1065 } 1066 return NO; 1067 } 1068 1069 1070 /** 1071 * Returns a list-iterator of the elements in this list (in proper 1072 * sequence), starting at the specified position in the list. 1073 * Obeys the general contract of {@code List.listIterator(NSInteger)}.<p> 1074 * 1075 * The list-iterator is <i>fail-fast</i>: if the list is structurally 1076 * modified at any time after the Iterator is created, in any way except 1077 * through the list-iterator's own {@code remove} or {@code add} 1078 * methods, the list-iterator will throw a 1079 * {@code ConcurrentModificationException}. Thus, in the face of 1080 * concurrent modification, the iterator fails quickly and cleanly, rather 1081 * than risking arbitrary, non-deterministic behavior at an undetermined 1082 * time in the future. 1083 * 1084 * @param index index of the first element to be returned from the 1085 * list-iterator (by a call to {@code next}) 1086 * @return a ListIterator of the elements in this list (in proper 1087 * sequence), starting at the specified position in the list 1088 * @throws IndexOutOfBoundsException {@inheritDoc} 1089 * @see List#listIterator(NSInteger) 1090 */ 1091 - (ListIterator *) listIterator:(NSInteger)index 1092 { 1093 [self checkPositionIndex:index]; 1094 return [[ListIterator newIterator:self withIndex:index] autorelease]; 1095 } 1096 1097 1098 /** 1099 * @since 1.6 1100 */ 1101 - (NSEnumerator *) descendingIterator 1102 { 1103 return [[[DescendingIterator alloc] init] autorelease]; 1104 } 1105 1106 /* 1107 - (LinkedList *) superClone:(NSZone *)zone 1108 { 1109 1110 @try { 1111 return (LinkedList *)[super copyWithZone:zone]; 1112 } 1113 @catch (CloneNotSupportedException * e) { 1114 @throw [[[NSException exceptionWithName:@"InternalException" reason:@"Attempted to Clone non-cloneable List" userInfo:nil] autorelease]; 1115 } 1116 } 1117 */ 1118 1119 /** 1120 * Returns a shallow copy of this {@code LinkedList}. (The elements 1121 * themselves are not cloned.) 1122 * 1123 * @return a shallow copy of this {@code LinkedList} instance 1124 */ 1125 - (id) copyWithZone:(NSZone *)zone 1126 { 1127 LinkedList *clone = [LinkedList allocWithZone:zone]; 1128 clone.first = nil; 1129 clone.last = nil; 1130 clone.count = 0; 1131 clone.modCount = 0; 1132 1133 for (LLNode *x = first; x != nil; x = x.next) 1134 [clone add:x.item]; 1135 1136 clone.count = count; 1137 clone.first = first; 1138 clone.last = last; 1139 return clone; 1140 } 1141 1142 1143 /** 1144 * Returns an array containing all of the elements in this list 1145 * in proper sequence (from first to last element). 1146 * 1147 * <p>The returned array will be "safe" in that no references to it are 1148 * maintained by this list. (In other words, this method must allocate 1149 * a new array). The caller is thus free to modify the returned array. 1150 * 1151 * <p>This method acts as bridge between array-based and collection-based 1152 * APIs. 1153 * 1154 * @return an array containing all of the elements in this list 1155 * in proper sequence 1156 */ 1157 - (NSArray *) toArray 1158 { 1159 AMutableArray *result = [AMutableArray arrayWithCapacity:10]; 1160 1161 for (LLNode *x = first; x != nil; x = x.next) 1162 [result addObject:x.item]; 1163 1164 return result; 1165 } 1166 1167 1168 /** 1169 * Returns an array containing all of the elements in this list in 1170 * proper sequence (from first to last element); the runtime type of 1171 * the returned array is that of the specified array. If the list fits 1172 * in the specified array, it is returned therein. Otherwise, a new 1173 * array is allocated with the runtime type of the specified array and 1174 * the size of this list. 1175 * 1176 * <p>If the list fits in the specified array with room to spare (i.e., 1177 * the array has more elements than the list), the element in the array 1178 * immediately following the end of the list is set to {@code null}. 1179 * (This is useful in determining the length of the list <i>only</i> if 1180 * the caller knows that the list does not contain any null elements.) 1181 * 1182 * <p>Like the {@link #toArray()} method, this method acts as bridge between 1183 * array-based and collection-based APIs. Further, this method allows 1184 * precise control over the runtime type of the output array, and may, 1185 * under certain circumstances, be used to save allocation costs. 1186 * 1187 * <p>Suppose {@code x} is a list known to contain only strings. 1188 * The following code can be used to dump the list into a newly 1189 * allocated array of {@code String}: 1190 * 1191 * <pre> 1192 * String[] y = x.toArray(new String[0]);</pre> 1193 * 1194 * Note that {@code toArray(new Object[0])} is identical in function to 1195 * {@code toArray()}. 1196 * 1197 * @param a the array into which the elements of the list are to 1198 * be stored, if it is big enough; otherwise, a new array of the 1199 * same runtime type is allocated for this purpose. 1200 * @return an array containing the elements of the list 1201 * @throws ArrayStoreException if the runtime type of the specified array 1202 * is not a supertype of the runtime type of every element in 1203 * this list 1204 * @throws NullPointerException if the specified array is null 1205 */ 1206 - (NSArray *) toArray:(AMutableArray *)a 1207 { 1208 if ( [a count] < count ) 1209 a = (AMutableArray *)[AMutableArray arrayWithArray:a]; 1210 AMutableArray *result = a; 1211 1212 for (LLNode *x = first; x != nil; x = x.next) 1213 [result addObject:x.item]; 1214 1215 if ([a count] > count) 1216 [a replaceObjectAtIndex:count withObject:nil]; 1217 return a; 1218 } 1219 1220 1221 /** 1222 * Saves the state of this {@code LinkedList} instance to a stream 1223 * (that is, serializes it). 1224 * 1225 * @serialData The size of the list (the number of elements it 1226 * contains) is emitted (NSInteger), followed by all of its 1227 * elements (each an Object) in the proper order. 1228 */ 1229 - (void) writeObject:(NSOutputStream *)s 1230 { 1231 /* 1232 [s defaultWriteObject]; 1233 [s writeInt:count]; 1234 1235 for (LLNode *x = first; x != nil; x = x.next) 1236 [s writeObject:x.item]; 1237 */ 1238 } 1239 1240 1241 /** 1242 * Reconstitutes this {@code LinkedList} instance from a stream 1243 * (that is, deserializes it). 1244 */ 1245 - (void) readObject:(NSInputStream *)s 1246 { 1247 /* 1248 [s defaultReadObject]; 1249 NSInteger len = [s readInt]; 1250 1251 for (NSInteger i = 0; i < len; i++) 1252 [self linkLast:(id)[s readObject]]; 1253 */ 1254 } 1255 1256 @end 1257