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