1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.text; 19 20/** 21 * An implementation of {@link CharacterIterator} for strings. 22 */ 23public final class StringCharacterIterator implements CharacterIterator { 24 25 String string; 26 27 int start, end, offset; 28 29 /** 30 * Constructs a new {@code StringCharacterIterator} on the specified string. 31 * The begin and current indices are set to the beginning of the string, the 32 * end index is set to the length of the string. 33 * 34 * @param value 35 * the source string to iterate over. 36 */ 37 public StringCharacterIterator(String value) { 38 string = value; 39 start = offset = 0; 40 end = string.length(); 41 } 42 43 /** 44 * Constructs a new {@code StringCharacterIterator} on the specified string 45 * with the current index set to the specified value. The begin index is set 46 * to the beginning of the string, the end index is set to the length of the 47 * string. 48 * 49 * @param value 50 * the source string to iterate over. 51 * @param location 52 * the current index. 53 * @throws IllegalArgumentException 54 * if {@code location} is negative or greater than the length 55 * of the source string. 56 */ 57 public StringCharacterIterator(String value, int location) { 58 string = value; 59 start = 0; 60 end = string.length(); 61 if (location < 0 || location > end) { 62 throw new IllegalArgumentException(); 63 } 64 offset = location; 65 } 66 67 /** 68 * Constructs a new {@code StringCharacterIterator} on the specified string 69 * with the begin, end and current index set to the specified values. 70 * 71 * @param value 72 * the source string to iterate over. 73 * @param start 74 * the index of the first character to iterate. 75 * @param end 76 * the index one past the last character to iterate. 77 * @param location 78 * the current index. 79 * @throws IllegalArgumentException 80 * if {@code start < 0}, {@code start > end}, {@code location < 81 * start}, {@code location > end} or if {@code end} is greater 82 * than the length of {@code value}. 83 */ 84 public StringCharacterIterator(String value, int start, int end, int location) { 85 string = value; 86 if (start < 0 || end > string.length() || start > end 87 || location < start || location > end) { 88 throw new IllegalArgumentException(); 89 } 90 this.start = start; 91 this.end = end; 92 offset = location; 93 } 94 95 /** 96 * Returns a new {@code StringCharacterIterator} with the same source 97 * string, begin, end, and current index as this iterator. 98 * 99 * @return a shallow copy of this iterator. 100 * @see java.lang.Cloneable 101 */ 102 @Override 103 public Object clone() { 104 try { 105 return super.clone(); 106 } catch (CloneNotSupportedException e) { 107 throw new AssertionError(e); 108 } 109 } 110 111 /** 112 * Returns the character at the current index in the source string. 113 * 114 * @return the current character, or {@code DONE} if the current index is 115 * past the end. 116 */ 117 public char current() { 118 if (offset == end) { 119 return DONE; 120 } 121 return string.charAt(offset); 122 } 123 124 /** 125 * Compares the specified object with this {@code StringCharacterIterator} 126 * and indicates if they are equal. In order to be equal, {@code object} 127 * must be an instance of {@code StringCharacterIterator} that iterates over 128 * the same sequence of characters with the same index. 129 * 130 * @param object 131 * the object to compare with this object. 132 * @return {@code true} if the specified object is equal to this 133 * {@code StringCharacterIterator}; {@code false} otherwise. 134 * @see #hashCode 135 */ 136 @Override 137 public boolean equals(Object object) { 138 if (!(object instanceof StringCharacterIterator)) { 139 return false; 140 } 141 StringCharacterIterator it = (StringCharacterIterator) object; 142 return string.equals(it.string) && start == it.start && end == it.end 143 && offset == it.offset; 144 } 145 146 /** 147 * Sets the current position to the begin index and returns the character at 148 * the new position in the source string. 149 * 150 * @return the character at the begin index or {@code DONE} if the begin 151 * index is equal to the end index. 152 */ 153 public char first() { 154 if (start == end) { 155 return DONE; 156 } 157 offset = start; 158 return string.charAt(offset); 159 } 160 161 /** 162 * Returns the begin index in the source string. 163 * 164 * @return the index of the first character of the iteration. 165 */ 166 public int getBeginIndex() { 167 return start; 168 } 169 170 /** 171 * Returns the end index in the source string. 172 * 173 * @return the index one past the last character of the iteration. 174 */ 175 public int getEndIndex() { 176 return end; 177 } 178 179 /** 180 * Returns the current index in the source string. 181 * 182 * @return the current index. 183 */ 184 public int getIndex() { 185 return offset; 186 } 187 188 @Override 189 public int hashCode() { 190 return string.hashCode() + start + end + offset; 191 } 192 193 /** 194 * Sets the current position to the end index - 1 and returns the character 195 * at the new position. 196 * 197 * @return the character before the end index or {@code DONE} if the begin 198 * index is equal to the end index. 199 */ 200 public char last() { 201 if (start == end) { 202 return DONE; 203 } 204 offset = end - 1; 205 return string.charAt(offset); 206 } 207 208 /** 209 * Increments the current index and returns the character at the new index. 210 * 211 * @return the character at the next index, or {@code DONE} if the next 212 * index would be past the end. 213 */ 214 public char next() { 215 if (offset >= (end - 1)) { 216 offset = end; 217 return DONE; 218 } 219 return string.charAt(++offset); 220 } 221 222 /** 223 * Decrements the current index and returns the character at the new index. 224 * 225 * @return the character at the previous index, or {@code DONE} if the 226 * previous index would be past the beginning. 227 */ 228 public char previous() { 229 if (offset == start) { 230 return DONE; 231 } 232 return string.charAt(--offset); 233 } 234 235 /** 236 * Sets the current index in the source string. 237 * 238 * @param location 239 * the index the current position is set to. 240 * @return the character at the new index, or {@code DONE} if 241 * {@code location} is set to the end index. 242 * @throws IllegalArgumentException 243 * if {@code location} is smaller than the begin index or greater 244 * than the end index. 245 */ 246 public char setIndex(int location) { 247 if (location < start || location > end) { 248 throw new IllegalArgumentException(); 249 } 250 offset = location; 251 if (offset == end) { 252 return DONE; 253 } 254 return string.charAt(offset); 255 } 256 257 /** 258 * Sets the source string to iterate over. The begin and end positions are 259 * set to the start and end of this string. 260 * 261 * @param value 262 * the new source string. 263 */ 264 public void setText(String value) { 265 string = value; 266 start = offset = 0; 267 end = value.length(); 268 } 269} 270