001/* 002 * Copyright 2001-2010 Stephen Colebourne 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.joda.primitives.list.impl; 017 018import java.util.Collection; 019import java.util.ConcurrentModificationException; 020import java.util.Iterator; 021import java.util.List; 022import java.util.NoSuchElementException; 023 024import org.joda.primitives.CharUtils; 025import org.joda.primitives.collection.impl.AbstractCharCollection; 026import org.joda.primitives.iterator.CharIterator; 027import org.joda.primitives.list.CharList; 028import org.joda.primitives.listiterator.CharListIterator; 029 030/** 031 * Abstract base class for lists of primitive <code>char</code> elements. 032 * <p> 033 * This class implements {@link java.util.Collection Collection} allowing 034 * seamless integration with other APIs. 035 * <p> 036 * The <code>get(int)</code> and <code>size()</code> methods must be 037 * implemented by subclases. 038 * To make the subclass modifiable, the <code>add(int, char)</code>, 039 * <code>removeIndex(int)</code> and set(int, char) must also be implemented. 040 * Subclasses may override other methods to increase efficiency. 041 * 042 * @author Stephen Colebourne 043 * @author Rodney Waldhoff 044 * @author Jason Tiscione 045 * @version CODE GENERATED 046 * @since 1.0 047 */ 048public abstract class AbstractCharList extends AbstractCharCollection implements CharList { 049 // This file is CODE GENERATED. Do not change manually. 050 051 /** 052 * Constructor. 053 */ 054 protected AbstractCharList() { 055 super(); 056 } 057 058 // CharList methods 059 //----------------------------------------------------------------------- 060 /** 061 * Gets an iterator over this list. 062 * 063 * @return an iterator over this list, not null 064 */ 065 public CharListIterator iterator() { 066 return listIterator(0); 067 } 068 069 /** 070 * Gets a list iterator over this list. 071 * <p> 072 * This implementation uses <code>charListIterator(int)</code>. 073 * 074 * @return an iterator over this list, not null 075 */ 076 public CharListIterator listIterator() { 077 return listIterator(0); 078 } 079 080 /** 081 * Gets a list iterator over this list from a start index. 082 * 083 * @param index the index to start from 084 * @return an iterator over this list, not null 085 * @throws IndexOutOfBoundsException if the index is invalid 086 */ 087 public CharListIterator listIterator(int index) { 088 checkIndex(index); 089 return new PListIterator(this, index); 090 } 091 092 /** 093 * Gets the first primitive value. 094 * 095 * @return value at index zero 096 * @throws IndexOutOfBoundsException if the size is zero 097 */ 098 public char firstChar() { 099 return getChar(0); 100 } 101 102 /** 103 * Gets the last primitive value. 104 * 105 * @return value at index <code>size() - 1</code> 106 * @throws IndexOutOfBoundsException if the size is zero 107 */ 108 public char lastChar() { 109 return getChar(size() - 1); 110 } 111 112 /** 113 * Checks whether this collection contains a specified primitive value. 114 * <p> 115 * This implementation uses <code>getChar(int)</code>. 116 * 117 * @param value the value to search for 118 * @return <code>true</code> if the value is found 119 */ 120 public boolean contains(char value) { 121 for (int i = 0, isize = size(); i < isize; i++) { 122 if (getChar(i) == value) { 123 return true; 124 } 125 } 126 return false; 127 } 128 129 /** 130 * Gets the first index of the specified primitive value. 131 * <p> 132 * This implementation uses <code>indexof(char, int)</code>. 133 * 134 * @param value the value to search for 135 * @return the zero-based index, or <code>-1</code> if not found 136 */ 137 public int indexOf(char value) { 138 return indexOf(value, 0); 139 } 140 141 /** 142 * Gets the first index of the specified primitive value from an index. 143 * <p> 144 * This method follows the conventions of <code>String</code> in that a 145 * negative index is treated as zero, and an index greater than the list 146 * size will simply return <code>-1</code>. 147 * <p> 148 * This implementation uses <code>get(int)</code>. 149 * 150 * @param value the value to search for 151 * @param fromIndexInclusive the index to start searching from, inclusive 152 * @return the zero-based index, or <code>-1</code> if not found 153 */ 154 public int indexOf(char value, int fromIndexInclusive) { 155 if (fromIndexInclusive < 0) { 156 fromIndexInclusive = 0; 157 } 158 for (int i = fromIndexInclusive, isize = size(); i < isize; i++) { 159 if (getChar(i) == value) { 160 return i; 161 } 162 } 163 return -1; 164 } 165 166 /** 167 * Gets the last index of the specified primitive value. 168 * <p> 169 * This implementation uses <code>lastIndexof(char, int)</code>. 170 * 171 * @param value the value to search for 172 * @return the zero-based index, or <code>-1</code> if not found 173 */ 174 public int lastIndexOf(char value) { 175 return lastIndexOf(value, size()); 176 } 177 178 /** 179 * Gets the first index of the specified primitive value from an index. 180 * <p> 181 * This method follows the conventions of <code>String</code> in that an 182 * index greater than the list size will start searching at the list size, 183 * and a negative index simply returns <code>-1</code>. 184 * <p> 185 * This implementation uses <code>get(int)</code>. 186 * 187 * @param value the value to search for 188 * @param fromIndexInclusive the index to start searching from, inclusive 189 * @return the zero-based index, or <code>-1</code> if not found 190 */ 191 public int lastIndexOf(char value, int fromIndexInclusive) { 192 if (fromIndexInclusive >= size()) { 193 fromIndexInclusive = size() - 1; 194 } 195 for (int i = fromIndexInclusive; i >= 0; i--) { 196 if (getChar(i) == value) { 197 return i; 198 } 199 } 200 return -1; 201 } 202 203 /** 204 * Gets the contents of the list as a String. 205 * 206 * @return the list contents 207 */ 208 public String toStringContents() { 209 return new String(toCharArray()); 210 } 211 212 /** 213 * Gets a range of elements as an array. 214 * 215 * @param fromIndexInclusive the index to start from, inclusive 216 * @param toIndexExclusive the index to end at, exclusive 217 * @return a new array containing a copy of the range of elements, not null 218 * @throws IndexOutOfBoundsException if either index is invalid 219 */ 220 public char[] toCharArray(int fromIndexInclusive, int toIndexExclusive) { 221 checkRange(fromIndexInclusive, toIndexExclusive); 222 223 if (fromIndexInclusive == toIndexExclusive) { 224 return CharUtils.EMPTY_CHAR_ARRAY; 225 } 226 int size = toIndexExclusive - fromIndexInclusive; 227 char[] result = new char[size]; 228 arrayCopy(fromIndexInclusive, result, 0, size); 229 return result; 230 } 231 232 /** 233 * Gets a range view of part of this list. 234 * <p> 235 * This method allows operations to work on a range within the greater list. 236 * Changes made to the either object will affect the other. 237 * 238 * @param fromIndexInclusive the index to start from, inclusive 239 * @param toIndexExclusive the index to end at, exclusive 240 * @return a new CharList for the subList, not null 241 * @throws IndexOutOfBoundsException if either index is invalid 242 */ 243 public CharList subList(int fromIndexInclusive, int toIndexExclusive) { 244 return null; // TODO 245 } 246 247 /** 248 * Clears the listof all elements (optional operation). 249 * <p> 250 * This implementation uses <code>removeRange(int, int)</code>. 251 * 252 * @throws UnsupportedOperationException if method not supported by this collection 253 */ 254 public void clear() { 255 removeRange(0, size()); 256 } 257 258 /** 259 * Adds a primitive value to this collection (optional operation). 260 * <p> 261 * This implementation uses <code>add(int, char)</code>. 262 * 263 * @param value the value to add to this collection 264 * @return <code>true</code> if this collection was modified by this method call 265 * @throws IllegalArgumentException if value is rejected by this collection 266 * @throws UnsupportedOperationException if not supported by this collection 267 */ 268 public boolean add(char value) { 269 checkAddModifiable(); 270 return add(size(), value); 271 } 272 273 /** 274 * Adds a primitive value to this list at an index (optional operation). 275 * <p> 276 * This implementation throws UnsupportedOperationException. 277 * 278 * @param index the index to add at 279 * @param value the value to add to this collection 280 * @return <code>true</code> if this list was modified by this method call 281 * @throws IndexOutOfBoundsException if the index is invalid 282 * @throws IllegalArgumentException if value is rejected by this collection 283 * @throws UnsupportedOperationException if not supported by this collection 284 */ 285 public boolean add(int index, char value) { 286 throw new UnsupportedOperationException("List does not support add"); 287 } 288 289 /** 290 * Adds an array of primitive values to this list at an index (optional operation). 291 * <p> 292 * This implementation uses <code>addAll(int, char)</code>. 293 * 294 * @param values the values to add to this collection, null treated as empty array 295 * @return <code>true</code> if this list was modified by this method call 296 * @throws IndexOutOfBoundsException if the index is invalid 297 * @throws IllegalArgumentException if value is rejected by this collection 298 * @throws UnsupportedOperationException if not supported by this collection 299 */ 300 public boolean addAll(char[] values) { 301 checkAddModifiable(); 302 return addAll(size(), values); 303 } 304 305 /** 306 * Adds an array of primitive values to this list at an index (optional operation). 307 * <p> 308 * This method is optional, throwing an UnsupportedOperationException if the 309 * collection cannot be added to. 310 * 311 * @param index the index to add at 312 * @param values the values to add to this collection, null treated as empty array 313 * @return <code>true</code> if this list was modified by this method call 314 * @throws IndexOutOfBoundsException if the index is invalid 315 * @throws IllegalArgumentException if value is rejected by this collection 316 * @throws UnsupportedOperationException if not supported by this collection 317 */ 318 public boolean addAll(int index, char[] values) { 319 checkAddModifiable(); 320 checkIndex(index); 321 boolean changed = false; 322 if (values != null) { 323 for (int i = 0; i < values.length; i++) { 324 changed |= add(index + i, values[i]); 325 } 326 } 327 return changed; 328 } 329 330 /** 331 * Removes a primitive value by index from the list (optional operation). 332 * <p> 333 * This implementation throws UnsupportedOperationException. 334 * 335 * @param index the index to remove from 336 * @return the primitive value previously at this index 337 * @throws IndexOutOfBoundsException if the index is invalid 338 * @throws UnsupportedOperationException if not supported by this collection 339 */ 340 public char removeCharAt(int index) { 341 throw new UnsupportedOperationException("List does not support remove"); 342 } 343 344 /** 345 * Removes the first occurrence of a primitive value from the list (optional operation). 346 * <p> 347 * This implementation uses <code>get(int)</code> and <code>removeCharAt(int)</code>. 348 * 349 * @param value the value to remove 350 * @return the primitive value previously at this index 351 * @throws UnsupportedOperationException if not supported by this collection 352 */ 353 public boolean removeChar(char value) { 354 checkRemoveModifiable(); 355 for (int i = 0, isize = size(); i < isize; i++) { 356 if (getChar(i) == value) { 357 removeCharAt(i); 358 return true; 359 } 360 } 361 return false; 362 } 363 364 /** 365 * Removes a range of values from the list (optional operation). 366 * <p> 367 * This implementation uses <code>removeCharAt(int)</code>. 368 * 369 * @param fromIndexInclusive the start of the range to remove, inclusive 370 * @param toIndexExclusive the end of the range to remove, exclusive 371 * @return <code>true</code> if the collection was modified 372 * @throws IndexOutOfBoundsException if the index is invalid 373 * @throws UnsupportedOperationException if remove is not supported 374 */ 375 public boolean removeRange(int fromIndexInclusive, int toIndexExclusive) { 376 checkRemoveModifiable(); 377 checkRange(fromIndexInclusive, toIndexExclusive); 378 if (fromIndexInclusive == toIndexExclusive) { 379 return false; 380 } 381 for (int i = size() - 1; i >= 0; i--) { 382 removeCharAt(i); 383 } 384 return true; 385 } 386 387 /** 388 * Sets the primitive value at a specified index. 389 * <p> 390 * This implementation throws UnsupportedOperationException. 391 * 392 * @param index the index to set 393 * @param value the value to store 394 * @return the previous value at the index 395 * @throws IndexOutOfBoundsException if the index is invalid 396 * @throws IllegalArgumentException if value is rejected by this collection 397 * @throws UnsupportedOperationException if not supported by this collection 398 */ 399 public char set(int index, char value) { 400 throw new UnsupportedOperationException("List does not support set"); 401 } 402 403 // List methods 404 //----------------------------------------------------------------------- 405 /** 406 * Gets the <code>Character</code> value at the specified index. 407 * 408 * @param index the index to get from 409 * @return value at the index 410 * @throws IndexOutOfBoundsException if the index is invalid 411 */ 412 public Character get(int index) { 413 return CharUtils.toObject(getChar(index)); 414 } 415 416 /** 417 * Gets the first <code>Character</code> value. 418 * 419 * @return value at index zero or null if the size is zero 420 */ 421 public Character first() { 422 if (size() == 0) { 423 return null; 424 } 425 return get(0); 426 } 427 428 /** 429 * Gets the last <code>Character</code> value. 430 * 431 * @return value at index <code>size() - 1</code> or null if the size is zero 432 */ 433 public Character last() { 434 if (size() == 0) { 435 return null; 436 } 437 return get(size() - 1); 438 } 439 440 /** 441 * Gets the first index of the specified <code>Character</code> value. 442 * 443 * @param value the value to search for 444 * @return the zero-based index, or <code>-1</code> if not found 445 * @throws NullPointerException if the value if null 446 * @throws ClassCastException if the object is not <code>Character</code> 447 */ 448 public int indexOf(Object value) { 449 return indexOf(CharUtils.toPrimitive(value)); 450 } 451 452 /** 453 * Gets the first index of the specified <code>Character</code> value from an index. 454 * <p> 455 * This method follows the conventions of <code>String</code> in that a 456 * negative index is treated as zero, and an index greater than the list 457 * size will simply return <code>-1</code>. 458 * 459 * @param value the value to search for 460 * @param fromIndexInclusive the index to start searching from, inclusive 461 * @return the zero-based index, or <code>-1</code> if not found 462 * @throws NullPointerException if the value if null 463 * @throws ClassCastException if the object is not <code>Character</code> 464 */ 465 public int indexOf(Object value, int fromIndexInclusive) { 466 return indexOf(CharUtils.toPrimitive(value), fromIndexInclusive); 467 } 468 469 /** 470 * Gets the last index of the specified <code>Character</code> value. 471 * 472 * @param value the value to search for 473 * @return the zero-based index, or <code>-1</code> if not found 474 * @throws NullPointerException if the value if null 475 * @throws ClassCastException if the object is not <code>Character</code> 476 */ 477 public int lastIndexOf(Object value) { 478 return lastIndexOf(CharUtils.toPrimitive(value)); 479 } 480 481 /** 482 * Gets the first index of the specified <code>Character</code> value from an index. 483 * <p> 484 * This method follows the conventions of <code>String</code> in that an 485 * index greater than the list size will start searching at the list size, 486 * and a negative index simply returns <code>-1</code>. 487 * 488 * @param value the value to search for 489 * @param fromIndexInclusive the index to start searching from, inclusive 490 * @return the zero-based index, or <code>-1</code> if not found 491 * @throws NullPointerException if the value if null 492 * @throws ClassCastException if the object is not <code>Character</code> 493 */ 494 public int lastIndexOf(Object value, int fromIndexInclusive) { 495 return lastIndexOf(CharUtils.toPrimitive(value), fromIndexInclusive); 496 } 497 498 /** 499 * Adds the <code>Character</code> value to this collection (optional operation). 500 * <p> 501 * This method is optional, throwing an UnsupportedOperationException if the 502 * collection cannot be added to. 503 * 504 * @param value the value to add to this collection 505 * @return <code>true</code> if this collection was modified by this method call 506 * @throws IllegalArgumentException if value is rejected by this collection 507 * @throws UnsupportedOperationException if not supported by this collection 508 */ 509 public boolean add(Character value) { 510 checkAddModifiable(); 511 return add(size(), CharUtils.toPrimitive(value)); 512 } 513 514 /** 515 * Adds the <code>Character</code> value to this list at an index (optional operation). 516 * <p> 517 * This method is optional, throwing an UnsupportedOperationException if the 518 * collection cannot be added to. 519 * 520 * @param index the index to add at 521 * @param value the value to add to this collection 522 * @throws IndexOutOfBoundsException if the index is invalid 523 * @throws ClassCastException if the object is not <code>Character</code> 524 * @throws IllegalArgumentException if value is rejected by this collection 525 * @throws UnsupportedOperationException if not supported by this collection 526 */ 527 public void add(int index, Character value) { 528 checkAddModifiable(); 529 checkIndex(index); 530 add(index, CharUtils.toPrimitive(value)); 531 } 532 533 /** 534 * Adds an array of <code>Character</code> values to this list at an index (optional operation). 535 * <p> 536 * This method is optional, throwing an UnsupportedOperationException if the 537 * collection cannot be added to. 538 * 539 * @param index the index to add at 540 * @param coll the values to add to this collection 541 * @return <code>true</code> if this list was modified by this method call 542 * @throws IndexOutOfBoundsException if the index is invalid 543 * @throws ClassCastException if any object is not <code>Character</code> 544 * @throws IllegalArgumentException if value is rejected by this collection 545 * @throws UnsupportedOperationException if not supported by this collection 546 */ 547 public boolean addAll(int index, Collection<? extends Character> coll) { 548 checkAddModifiable(); 549 checkIndex(index); 550 return addAll(index, CharUtils.toPrimitiveArray(coll)); 551 } 552 553 /** 554 * Removes a primitive value by index from the list (optional operation). 555 * <p> 556 * This implementation uses <code>removeCharAt(int)</code>. 557 * 558 * @deprecated This method should only be used when working with List and 559 * not when working with CharList - use <code>removeCharAt(int)</code> 560 * @param index the index to remove from 561 * @return the primitive value previously at this index 562 * @throws IndexOutOfBoundsException if the index is invalid 563 * @throws UnsupportedOperationException if not supported by this collection 564 */ 565 public Character remove(int index) { 566 checkRemoveModifiable(); 567 return CharUtils.toObject(removeCharAt(index)); 568 } 569 570 /** 571 * Sets the <code>Character</code> value at a specified index. 572 * <p> 573 * This implementation uses <code>set(int, char)</code>. 574 * 575 * @param index the index to set 576 * @param value the value to store 577 * @return the previous value at the index 578 * @throws IndexOutOfBoundsException if the index is invalid 579 * @throws IllegalArgumentException if value is rejected by this collection 580 * @throws UnsupportedOperationException if not supported by this collection 581 */ 582 public Character set(int index, Character value) { 583 checkSetModifiable(); 584 checkIndexExists(index); 585 return CharUtils.toObject(set(index, CharUtils.toPrimitive(value))); 586 } 587 588 //----------------------------------------------------------------------- 589 /** 590 * Compares this list to another as per the contract of <code>List</code>. 591 * 592 * @param obj the object to compare to 593 * @return <code>true</code> if the lists are equal 594 */ 595 public boolean equals(Object obj) { 596 if (obj == this) { 597 return true; 598 } 599 if (obj instanceof CharList) { 600 CharList other = (CharList) obj; 601 if (size() != other.size()) { 602 return false; 603 } 604 CharIterator it1 = listIterator(); 605 CharIterator it2 = other.listIterator(); 606 while (it1.hasNext() && it2.hasNext()) { 607 if (it1.nextChar() != it2.nextChar()) { 608 return false; 609 } 610 } 611 return true; 612 } else if (obj instanceof List<?>) { 613 List<?> other = (List<?>) obj; 614 if (size() != other.size()) { 615 return false; 616 } 617 CharIterator it1 = listIterator(); 618 Iterator<?> it2 = other.listIterator(); 619 while (it1.hasNext() && it2.hasNext()) { 620 Object next = it2.next(); 621 if (isToPrimitivePossible(next) == false) { 622 return false; 623 } 624 if (it1.nextChar() != toPrimitive(next)) { 625 return false; 626 } 627 } 628 return true; 629 } else { 630 return false; 631 } 632 } 633 634 /** 635 * Gets the hashCode of this list as per the contract of <code>List</code>. 636 * 637 * @return the hash code for this list 638 */ 639 public int hashCode() { 640 int hashCode = 1; 641 Iterator<Character> it = iterator(); 642 while (it.hasNext()) { 643 Object obj = it.next(); 644 hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); 645 } 646 return hashCode; 647 } 648 649 //----------------------------------------------------------------------- 650 /** 651 * Copies data from this collection into the specified array. 652 * This method is pre-validated. 653 * 654 * @param fromIndex the index to start from 655 * @param dest the destination array 656 * @param destIndex the destination start index 657 * @param size the number of items to copy 658 */ 659 protected void arrayCopy(int fromIndex, char[] dest, int destIndex, int size) { 660 for (int i = 0; i < size; i++) { 661 dest[i + destIndex] = getChar(i + fromIndex); 662 } 663 } 664 665 /** 666 * Are the set methods supported. 667 * <p> 668 * This implementation returns false. 669 * 670 * @return true if supported 671 */ 672 protected boolean isSetModifiable() { 673 return false; 674 } 675 676 /** 677 * Is the collection modifiable in any way. 678 * 679 * @return true if supported 680 */ 681 public boolean isModifiable() { 682 return isAddModifiable() || isRemoveModifiable() || isSetModifiable(); 683 } 684 685 /** 686 * Check whether add is suported and throw an exception. 687 */ 688 protected void checkSetModifiable() { 689 if (isSetModifiable() == false) { 690 throw new UnsupportedOperationException("Collection does not support set"); 691 } 692 } 693 694 /** 695 * Checks whether an index is valid or not. 696 * 697 * @param index the index to check 698 * @throws IndexOutOfBoundsException if either index is invalid 699 */ 700 protected void checkIndexExists(int index) { 701 if (index < 0) { 702 throw new ArrayIndexOutOfBoundsException( 703 "Index less than zero: " + index + " < 0"); 704 } 705 if (index >= size()) { 706 throw new ArrayIndexOutOfBoundsException( 707 "Index greater than/equal to size(): " + index + " >= " + size()); 708 } 709 } 710 711 /** 712 * Checks whether an index is valid or not. 713 * 714 * @param index the index to check 715 * @throws IndexOutOfBoundsException if either index is invalid 716 */ 717 protected void checkIndex(int index) { 718 if (index < 0) { 719 throw new ArrayIndexOutOfBoundsException( 720 "Index less than zero: " + index + " < 0"); 721 } 722 if (index > size()) { 723 throw new ArrayIndexOutOfBoundsException( 724 "Index greater than size(): " + index + " > " + size()); 725 } 726 } 727 728 /** 729 * Checks whether a range is valid or not. 730 * 731 * @param fromIndexInclusive the index to start from, inclusive 732 * @param toIndexExclusive the index to end at, exclusive 733 * @throws IndexOutOfBoundsException if either index is invalid 734 */ 735 protected void checkRange(int fromIndexInclusive, int toIndexExclusive) { 736 if (fromIndexInclusive < 0) { 737 throw new ArrayIndexOutOfBoundsException( 738 "From index less than zero: " + fromIndexInclusive + " < 0"); 739 } 740 if (toIndexExclusive > size()) { 741 throw new ArrayIndexOutOfBoundsException( 742 "To index greater than size(): " + toIndexExclusive + " > " + size()); 743 } 744 if (fromIndexInclusive > toIndexExclusive) { 745 throw new ArrayIndexOutOfBoundsException( 746 "To index greater than from index: " + fromIndexInclusive + " > " + toIndexExclusive); 747 } 748 } 749 750 //----------------------------------------------------------------------- 751 /** 752 * List iterator. 753 */ 754 protected static class PListIterator implements CharListIterator { 755 756 private final AbstractCharList iList; 757 private final int iStart; 758 private int iCursor = 0; 759 private int iLastIndex = -1; 760 761 protected PListIterator(AbstractCharList list, int start) { 762 super(); 763 this.iList = list; 764 this.iStart = start; 765 this.iCursor = start; 766 } 767 768 //----------------------------------------------------------------------- 769 public boolean hasNext() { 770 return (iCursor < iList.size()); 771 } 772 773 public char nextChar() { 774 if (hasNext() == false) { 775 throw new NoSuchElementException("No more elements available"); 776 } 777 iLastIndex = iCursor; 778 return iList.getChar(iCursor++); 779 } 780 781 public Character next() { 782 return iList.toObject(nextChar()); 783 } 784 785 public int nextIndex() { 786 return iCursor; 787 } 788 789 //----------------------------------------------------------------------- 790 public boolean hasPrevious() { 791 return (iCursor > 0); 792 } 793 794 public char previousChar() { 795 if (hasPrevious() == false) { 796 throw new NoSuchElementException("No more elements available"); 797 } 798 iLastIndex = --iCursor; 799 return iList.getChar(iCursor); 800 } 801 802 public Character previous() { 803 return iList.toObject(previousChar()); 804 } 805 806 public int previousIndex() { 807 return iCursor - 1; 808 } 809 810 //----------------------------------------------------------------------- 811 public void remove() { 812 iList.checkRemoveModifiable(); 813 if (iLastIndex == -1) { 814 throw new IllegalStateException("Element cannot be removed"); 815 } 816 iList.removeCharAt(iLastIndex); 817 iCursor = iLastIndex; 818 iLastIndex = -1; 819 } 820 821 public void add(char value) { 822 iList.checkAddModifiable(); 823 try { 824 iList.add(iCursor++, value); 825 iLastIndex = -1; 826 } catch (IndexOutOfBoundsException ex) { 827 throw new ConcurrentModificationException("The underlying list was modified"); 828 } 829 } 830 831 public void add(Character obj) { 832 iList.checkAddModifiable(); 833 add(iList.toPrimitive(obj)); 834 } 835 836 public void set(char value) { 837 iList.checkSetModifiable(); 838 if (iLastIndex == -1) { 839 throw new IllegalStateException("Element cannot be set"); 840 } 841 try { 842 iList.set(iLastIndex, value); 843 } catch (IndexOutOfBoundsException ex) { 844 throw new ConcurrentModificationException("The underlying list was modified"); 845 } 846 } 847 848 public void set(Character obj) { 849 iList.checkSetModifiable(); 850 set(iList.toPrimitive(obj)); 851 } 852 853 //----------------------------------------------------------------------- 854 public boolean isModifiable() { 855 return iList.isModifiable(); 856 } 857 858 public boolean isResettable() { 859 return true; 860 } 861 862 public void reset() { 863 iCursor = iStart; 864 } 865 866 } 867 868} 869