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 18 package java.util; 19 20 /** 21 * Breaks a string into tokens; new code should probably use {@link String#split}. 22 * 23 * <blockquote> 24 * <pre> 25 * // Legacy code: 26 * StringTokenizer st = new StringTokenizer("a:b:c", ":"); 27 * while (st.hasMoreTokens()) { 28 * System.err.println(st.nextToken()); 29 * } 30 * 31 * // New code: 32 * for (String token : "a:b:c".split(":")) { 33 * System.err.println(token); 34 * } 35 * </pre> 36 * </blockquote> 37 * 38 * @since 1.0 39 */ 40 public class StringTokenizer implements Enumeration<Object> { 41 42 private String string; 43 44 private String delimiters; 45 46 private boolean returnDelimiters; 47 48 private int position; 49 50 /** 51 * Constructs a new {@code StringTokenizer} for the parameter string using 52 * whitespace as the delimiter. The {@code returnDelimiters} flag is set to 53 * {@code false}. 54 * 55 * @param string 56 * the string to be tokenized. 57 */ StringTokenizer(String string)58 public StringTokenizer(String string) { 59 this(string, " \t\n\r\f", false); 60 } 61 62 /** 63 * Constructs a new {@code StringTokenizer} for the parameter string using 64 * the specified delimiters. The {@code returnDelimiters} flag is set to 65 * {@code false}. If {@code delimiters} is {@code null}, this constructor 66 * doesn't throw an {@code Exception}, but later calls to some methods might 67 * throw a {@code NullPointerException}. 68 * 69 * @param string 70 * the string to be tokenized. 71 * @param delimiters 72 * the delimiters to use. 73 */ StringTokenizer(String string, String delimiters)74 public StringTokenizer(String string, String delimiters) { 75 this(string, delimiters, false); 76 } 77 78 /** 79 * Constructs a new {@code StringTokenizer} for the parameter string using 80 * the specified delimiters, returning the delimiters as tokens if the 81 * parameter {@code returnDelimiters} is {@code true}. If {@code delimiters} 82 * is null this constructor doesn't throw an {@code Exception}, but later 83 * calls to some methods might throw a {@code NullPointerException}. 84 * 85 * @param string 86 * the string to be tokenized. 87 * @param delimiters 88 * the delimiters to use. 89 * @param returnDelimiters 90 * {@code true} to return each delimiter as a token. 91 */ StringTokenizer(String string, String delimiters, boolean returnDelimiters)92 public StringTokenizer(String string, String delimiters, 93 boolean returnDelimiters) { 94 if (string == null) { 95 throw new NullPointerException("string == null"); 96 } 97 this.string = string; 98 this.delimiters = delimiters; 99 this.returnDelimiters = returnDelimiters; 100 this.position = 0; 101 } 102 103 /** 104 * Returns the number of unprocessed tokens remaining in the string. 105 * 106 * @return number of tokens that can be retreived before an {@code 107 * Exception} will result from a call to {@code nextToken()}. 108 */ countTokens()109 public int countTokens() { 110 int count = 0; 111 boolean inToken = false; 112 for (int i = position, length = string.length(); i < length; i++) { 113 if (delimiters.indexOf(string.charAt(i), 0) >= 0) { 114 if (returnDelimiters) 115 count++; 116 if (inToken) { 117 count++; 118 inToken = false; 119 } 120 } else { 121 inToken = true; 122 } 123 } 124 if (inToken) 125 count++; 126 return count; 127 } 128 129 /** 130 * Returns {@code true} if unprocessed tokens remain. This method is 131 * implemented in order to satisfy the {@code Enumeration} interface. 132 * 133 * @return {@code true} if unprocessed tokens remain. 134 */ hasMoreElements()135 public boolean hasMoreElements() { 136 return hasMoreTokens(); 137 } 138 139 /** 140 * Returns {@code true} if unprocessed tokens remain. 141 * 142 * @return {@code true} if unprocessed tokens remain. 143 */ hasMoreTokens()144 public boolean hasMoreTokens() { 145 if (delimiters == null) { 146 throw new NullPointerException("delimiters == null"); 147 } 148 int length = string.length(); 149 if (position < length) { 150 if (returnDelimiters) 151 return true; // there is at least one character and even if 152 // it is a delimiter it is a token 153 154 // otherwise find a character which is not a delimiter 155 for (int i = position; i < length; i++) 156 if (delimiters.indexOf(string.charAt(i), 0) == -1) 157 return true; 158 } 159 return false; 160 } 161 162 /** 163 * Returns the next token in the string as an {@code Object}. This method is 164 * implemented in order to satisfy the {@code Enumeration} interface. 165 * 166 * @return next token in the string as an {@code Object} 167 * @throws NoSuchElementException 168 * if no tokens remain. 169 */ nextElement()170 public Object nextElement() { 171 return nextToken(); 172 } 173 174 /** 175 * Returns the next token in the string as a {@code String}. 176 * 177 * @return next token in the string as a {@code String}. 178 * @throws NoSuchElementException 179 * if no tokens remain. 180 */ nextToken()181 public String nextToken() { 182 if (delimiters == null) { 183 throw new NullPointerException("delimiters == null"); 184 } 185 int i = position; 186 int length = string.length(); 187 188 if (i < length) { 189 if (returnDelimiters) { 190 if (delimiters.indexOf(string.charAt(position), 0) >= 0) 191 return String.valueOf(string.charAt(position++)); 192 for (position++; position < length; position++) 193 if (delimiters.indexOf(string.charAt(position), 0) >= 0) 194 return string.substring(i, position); 195 return string.substring(i); 196 } 197 198 while (i < length && delimiters.indexOf(string.charAt(i), 0) >= 0) 199 i++; 200 position = i; 201 if (i < length) { 202 for (position++; position < length; position++) 203 if (delimiters.indexOf(string.charAt(position), 0) >= 0) 204 return string.substring(i, position); 205 return string.substring(i); 206 } 207 } 208 throw new NoSuchElementException(); 209 } 210 211 /** 212 * Returns the next token in the string as a {@code String}. The delimiters 213 * used are changed to the specified delimiters. 214 * 215 * @param delims 216 * the new delimiters to use. 217 * @return next token in the string as a {@code String}. 218 * @throws NoSuchElementException 219 * if no tokens remain. 220 */ nextToken(String delims)221 public String nextToken(String delims) { 222 this.delimiters = delims; 223 return nextToken(); 224 } 225 } 226