1 |
/* java.lang.String |
/* String.java -- immutable character sequences; the object of string literals |
2 |
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. |
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
7 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
8 |
the Free Software Foundation; either version 2, or (at your option) |
the Free Software Foundation; either version 2, or (at your option) |
9 |
any later version. |
any later version. |
10 |
|
|
11 |
GNU Classpath is distributed in the hope that it will be useful, but |
GNU Classpath is distributed in the hope that it will be useful, but |
12 |
WITHOUT ANY WARRANTY; without even the implied warranty of |
WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
41 |
import java.util.Comparator; |
import java.util.Comparator; |
42 |
import java.util.Hashtable; |
import java.util.Hashtable; |
43 |
import java.util.Locale; |
import java.util.Locale; |
44 |
|
import java.util.regex.Pattern; |
45 |
import gnu.java.io.EncodingManager; |
import gnu.java.io.EncodingManager; |
46 |
import java.io.*; |
import java.io.Serializable; |
47 |
|
import java.io.UnsupportedEncodingException; |
48 |
|
import java.io.CharConversionException; |
49 |
|
|
50 |
/** |
/** |
51 |
* Strings represent an immutable set of characters. |
* Strings represent an immutable set of characters. All String literals |
52 |
* Compliant with JDK 1.1. |
* are instances of this class, and two string literals with the same contents |
53 |
|
* refer to the same String object. |
54 |
|
* |
55 |
|
* <p>This class also includes a number of methods for manipulating the |
56 |
|
* contents of strings (of course, creating a new object if there are any |
57 |
|
* changes, as String is immutable). Case mapping relies on Unicode 3.0.0 |
58 |
|
* standards, where some character sequences have a different number of |
59 |
|
* characters in the uppercase version than the lower case. |
60 |
|
* |
61 |
|
* <p>Strings are special, in that they are the only object with an overloaded |
62 |
|
* operator. When you use '+' with at least one String argument, both |
63 |
|
* arguments have String conversion performed on them, and another String (not |
64 |
|
* guaranteed to be unique) results. |
65 |
|
* |
66 |
|
* <p>String is special-cased when doing data serialization - rather than |
67 |
|
* listing the fields of this class, a String object is converted to a string |
68 |
|
* literal in the object stream. |
69 |
* |
* |
70 |
* @author Paul N. Fisher |
* @author Paul N. Fisher |
71 |
* @author Eric Blake <ebb9@email.byu.edu> |
* @author Eric Blake <ebb9@email.byu.edu> |
72 |
* @since JDK1.0 |
* @since 1.0 |
73 |
|
* @status updated to 1.3, waiting on java.util.regex, and could use better |
74 |
|
* data sharing |
75 |
*/ |
*/ |
76 |
public final class String implements Comparable, CharSequence, Serializable { |
public final class String implements Serializable, Comparable, CharSequence |
77 |
|
{ |
78 |
|
/** |
79 |
|
* This is probably not necessary because this class is special cased already |
80 |
|
* but it will avoid showing up as a discrepancy when comparing SUIDs. |
81 |
|
*/ |
82 |
|
private static final long serialVersionUID = -6849794470754667710L; |
83 |
|
|
84 |
/** |
/** |
85 |
* Holds the references for each intern()'d String. |
* Holds the references for each intern()'d String. |
86 |
* Once a String has been intern()'d it cannot be GC'd. |
* Once a String has been intern()'d it cannot be GC'd. |
87 |
* |
* |
88 |
* @XXX Replace with a weak reference structure for 1.2 |
* @XXX Replace with a weak reference structure for 1.2 |
89 |
*/ |
*/ |
90 |
private static Hashtable internTable = new Hashtable(); |
private static final Hashtable internTable = new Hashtable(); |
91 |
|
|
92 |
/** |
/** |
93 |
* Characters which make up the String. |
* Characters which make up the String. |
94 |
* Package access is granted for use by StringBuffer. |
* Package access is granted for use by StringBuffer. |
95 |
*/ |
*/ |
96 |
char[] value; |
final char[] value; |
97 |
|
|
98 |
/** |
/** |
99 |
* Holds the number of characters in str[]. This number is generally |
* Holds the number of characters in str[]. This number is generally |
101 |
* with this String, then len will be equal to StringBuffer.length(). |
* with this String, then len will be equal to StringBuffer.length(). |
102 |
* Package access is granted for use by StringBuffer. |
* Package access is granted for use by StringBuffer. |
103 |
*/ |
*/ |
104 |
int count; |
final int count; |
105 |
|
|
106 |
/** |
/** |
107 |
* Holds the starting position for characters in str[]. Since |
* Holds the starting position for characters in str[]. Since |
108 |
* substring()'s are common, the use of `offset' allows the operation |
* substring()'s are common, the use of offset allows the operation |
109 |
* to perform in O(1). |
* to perform in O(1). Package access is granted for use by StringBuffer. |
110 |
* |
* |
111 |
* @FIXME The use of offset has not been implemented. |
* @XXX The use of offset has not been implemented. |
112 |
*/ |
*/ |
113 |
private int offset; |
final int offset = 0; |
114 |
|
|
115 |
/** |
/** |
116 |
* Caches the result of hashCode(). If this value is zero, the hashcode |
* Caches the result of hashCode(). If this value is zero, the hashcode |
132 |
private static final long serialVersionUID = 8575799808933029326L; |
private static final long serialVersionUID = 8575799808933029326L; |
133 |
|
|
134 |
/** |
/** |
135 |
* The default private constructor generates unnecessary overhead |
* The default private constructor generates unnecessary overhead. |
136 |
*/ |
*/ |
137 |
CaseInsensitiveComparator() {} |
CaseInsensitiveComparator() {} |
138 |
|
|
139 |
/** |
/** |
140 |
* Compares to Strings, using |
* Compares to Strings, using |
141 |
* <code>String.compareToIgnoreCase(String)</code>. |
* <code>String.compareToIgnoreCase(String)</code>. |
142 |
* |
* |
143 |
* @param o1 the first string |
* @param o1 the first string |
144 |
* @param o2 the second string |
* @param o2 the second string |
145 |
* @return < 0, 0, or > 0 depending on the case-insensitive |
* @return < 0, 0, or > 0 depending on the case-insensitive |
152 |
{ |
{ |
153 |
return ((String) o1).compareToIgnoreCase((String) o2); |
return ((String) o1).compareToIgnoreCase((String) o2); |
154 |
} |
} |
155 |
} |
} // class CaseInsensitiveComparator |
156 |
|
|
157 |
/** |
/** |
158 |
* A Comparator that uses <code>String.compareToIgnoreCase(String)</code>. |
* A Comparator that uses <code>String.compareToIgnoreCase(String)</code>. |
159 |
* This comparator is {@link Serializable}. |
* This comparator is {@link Serializable}. Note that it ignores Locale, |
160 |
|
* for that, you want a Collator. |
161 |
* |
* |
162 |
|
* @see Collator#compare(String, String) |
163 |
* @since 1.2 |
* @since 1.2 |
164 |
*/ |
*/ |
165 |
public static final Comparator CASE_INSENSITIVE_ORDER |
public static final Comparator CASE_INSENSITIVE_ORDER |
166 |
= new CaseInsensitiveComparator(); |
= new CaseInsensitiveComparator(); |
167 |
|
|
168 |
/** |
/** |
169 |
* Creates an empty String (length 0) |
* Creates an empty String (length 0). Unless you really need a new object, |
170 |
|
* consider using <code>""</code> instead. |
171 |
*/ |
*/ |
172 |
public String() { |
public String() { |
173 |
value = new char[0]; |
value = new char[0]; |
174 |
|
count = 0; |
175 |
} |
} |
176 |
|
|
177 |
/** |
/** |
178 |
* Copies the contents of a String to a new String. |
* Copies the contents of a String to a new String. Since Strings are |
179 |
* Since Strings are immutable, only a shallow copy is performed. |
* immutable, only a shallow copy is performed. |
180 |
* |
* |
181 |
* @param str String to copy |
* @param str String to copy |
182 |
* |
* @throws NullPointerException if value is null |
|
* @exception NullPointerException if `value' is null |
|
183 |
*/ |
*/ |
184 |
public String(String str) throws NullPointerException { |
public String(String str) |
185 |
// since Strings are immutable, there's no reason to |
{ |
186 |
// make a deep copy of `value' |
// Since Strings are immutable, don't copy value. |
187 |
value = str.value; |
value = str.value; |
188 |
count = str.count; |
count = str.count; |
189 |
} |
} |
190 |
|
|
191 |
/** |
/** |
192 |
* Creates a new String using the character sequence represented by |
* Creates a new String using the character sequence of the char array. |
193 |
* the StringBuffer. |
* Subsequent changes to data do not affect the String. |
|
* |
|
|
* @param value StringBuffer to copy |
|
|
* |
|
|
* @exception NullPointerException if `value' is null |
|
|
*/ |
|
|
public String(StringBuffer buf) throws NullPointerException { |
|
|
count = buf.length(); |
|
|
value = new char[count]; |
|
|
buf.getChars(0, buf.length(), value, 0); |
|
|
} |
|
|
|
|
|
/** |
|
|
* Creates a new String using the character sequence of the char |
|
|
* array. |
|
194 |
* |
* |
195 |
* @param data char array to copy |
* @param data char array to copy |
196 |
* |
* @throws NullPointerException if data is null |
|
* @exception NullPointerException if `data' is null |
|
197 |
*/ |
*/ |
198 |
public String(char[] data) throws NullPointerException { |
public String(char[] data) |
199 |
|
{ |
200 |
count = data.length; |
count = data.length; |
201 |
value = new char[count]; |
value = (char[]) data.clone(); |
|
System.arraycopy(data, 0, value, 0, data.length); |
|
202 |
} |
} |
203 |
|
|
204 |
/** |
/** |
205 |
* Creates a new String using the character sequence of the char |
* Creates a new String using the character sequence of a subarray of |
206 |
* array, starting at the offset, and copying chars up |
* characters. The string starts at offset, and copies count chars. |
207 |
* to the count. |
* Subsequent changes to data do not affect the String. |
208 |
* |
* |
209 |
* @param data char array to copy |
* @param data char array to copy |
210 |
* @param offset position (base 0) to start copying out of `data' |
* @param offset position (base 0) to start copying out of data |
211 |
* @param count the number of characters from `data' to copy |
* @param count the number of characters from data to copy |
212 |
* |
* @throws NullPointerException if data is null |
213 |
* @exception NullPointerException if `data' is null |
* @throws IndexOutOfBoundsException if (offset < 0 || count < 0 |
214 |
* @exception StringIndexOutOfBoundsException |
* || offset + count > data.length) |
215 |
* if (offset < 0 || count < 0 || offset+count > data.length) |
* (while unspecified, this is a StringIndexOutOfBoundsException) |
216 |
*/ |
*/ |
217 |
public String(char[] data, int offset, int count) |
public String(char[] data, int offset, int count) |
218 |
throws NullPointerException, IndexOutOfBoundsException { |
{ |
219 |
if (offset < 0 || count < 0 || offset+count > data.length) |
if (offset < 0 || count < 0 || offset + count > data.length) |
220 |
throw new StringIndexOutOfBoundsException(); |
throw new StringIndexOutOfBoundsException(); |
221 |
this.count = count; |
this.count = count; |
222 |
value = new char[count]; |
value = new char[count]; |
224 |
} |
} |
225 |
|
|
226 |
/** |
/** |
227 |
* Creates a new String using the byte array. |
* Creates a new String using an 8-bit array of integer values, starting at |
228 |
* |
* an offset, and copying up to the count. Each character c, using |
229 |
* Uses the default encoding for the system to decode the byte array, or if |
* corresponding byte b, is created in the new String as if by performing: |
|
* that doesn't work, uses 8859_1. |
|
230 |
* |
* |
231 |
* @param data byte array to copy |
* <pre> |
232 |
|
* c = (char) (((hibyte & 0xff) << 8) | (b & 0xff)) |
233 |
|
* </pre> |
234 |
* |
* |
235 |
* @exception NullPointerException if `data' is null |
* @param ascii array of integer values |
236 |
|
* @param hibyte top byte of each Unicode character |
237 |
|
* @param offset position (base 0) to start copying out of ascii |
238 |
|
* @param count the number of characters from ascii to copy |
239 |
|
* @throws NullPointerException if ascii is null |
240 |
|
* @throws IndexOutOfBoundsException if (offset < 0 || count < 0 |
241 |
|
* || offset + count > ascii.length) |
242 |
|
* (while unspecified, this is a StringIndexOutOfBoundsException) |
243 |
|
* @see #String(byte[]) |
244 |
|
* @see #String(byte[], String) |
245 |
|
* @see #String(byte[], int, int) |
246 |
|
* @see #String(byte[], int, int, String) |
247 |
|
* @deprecated use {@link #String(byte[], int, int, String)} to perform |
248 |
|
* correct encoding |
249 |
*/ |
*/ |
250 |
public String(byte[] data) throws NullPointerException { |
public String(byte[] ascii, int hibyte, int offset, int count) |
251 |
try { |
{ |
252 |
value = EncodingManager.getDecoder().convertToChars(data); |
if (offset < 0 || count < 0 || offset + count > ascii.length) |
253 |
} catch (CharConversionException cce) { |
throw new StringIndexOutOfBoundsException(); |
254 |
try { |
this.count = count; |
255 |
value = EncodingManager.getDecoder("8859_1").convertToChars(data); |
value = new char[count]; |
256 |
} catch (IOException ioe) { |
for (int i = 0; i < count; i++) |
257 |
throw new Error(ioe.toString()); |
value[i] = (char) (((hibyte & 0xff) << 8) | (ascii[i + offset] & 0xff)); |
|
} |
|
|
} |
|
|
count = value.length; |
|
258 |
} |
} |
259 |
|
|
260 |
/** |
/** |
261 |
* Creates a new String using the byte array. |
* Creates a new String using an 8-bit array of integer values. Each |
262 |
|
* character c, using corresponding byte b, is created in the new String |
263 |
|
* as if by performing: |
264 |
* |
* |
265 |
* Uses the specified encoding type to decode the byte array, or if |
* <pre> |
266 |
* that doesn't work, uses 8859_1. |
* c = (char) (((hibyte & 0xff) << 8) | (b & 0xff)) |
267 |
|
* </pre> |
268 |
* |
* |
269 |
* @param data byte array to copy |
* @param ascii array of integer values |
270 |
* @param encoding the name of the encoding to use |
* @param hibyte top byte of each Unicode character |
271 |
* @exception NullPointerException if `data' is null. |
* @throws NullPointerException if ascii is null |
272 |
* @exception UnsupportedEncodingException if the specified encoding is not |
* @see #String(byte[]) |
273 |
* found. |
* @see #String(byte[], String) |
274 |
*/ |
* @see #String(byte[], int, int) |
275 |
public String(byte[] data, String encoding) |
* @see #String(byte[], int, int, String) |
276 |
throws NullPointerException, UnsupportedEncodingException { |
* @see #String(byte[], int, int, int) |
277 |
try { |
* @deprecated use {@link #String(byte[], String)} to perform |
278 |
value = EncodingManager.getDecoder(encoding).convertToChars(data); |
* correct encoding |
279 |
} catch (CharConversionException cce) { |
*/ |
280 |
try { |
public String(byte[] ascii, int hibyte) |
281 |
value = EncodingManager.getDecoder("8859_1").convertToChars(data); |
{ |
282 |
} catch (IOException ioe) { |
this(ascii, hibyte, 0, ascii.length); |
|
throw new Error(ioe.toString()); |
|
|
} |
|
|
} |
|
|
count = value.length; |
|
283 |
} |
} |
284 |
|
|
285 |
/** |
/** |
286 |
* Creates a new String using the portion of the byte array starting at the |
* Creates a new String using the portion of the byte array starting at the |
287 |
* offset and ending at offset+count. |
* offset and ending at offset + count. Uses the specified encoding type |
288 |
* |
* to decode the byte array, so the resulting string may be longer or |
289 |
* Uses the specified encoding type to decode the byte array, or if |
* shorter than the byte array. For more decoding control, use |
290 |
* that doesn't work, uses 8859_1. |
* {@link java.nio.charset.CharsetDecoder}, and for valid character sets, |
291 |
|
* see {@link java.nio.charset.Charset}. The behavior is not specified if |
292 |
|
* the decoder encounters invalid characters; this implementation throws |
293 |
|
* an Error. |
294 |
* |
* |
295 |
* @param data byte array to copy |
* @param data byte array to copy |
296 |
* @param offset the offset to start at |
* @param offset the offset to start at |
297 |
* @param count the number of characters in the array to use |
* @param count the number of characters in the array to use |
298 |
* @param encoding the name of the encoding to use |
* @param encoding the name of the encoding to use |
299 |
* @exception NullPointerException if `data' is null. |
* @throws NullPointerException if data or encoding is null |
300 |
* @exception IndexOutOfBoundsException if the specified offset or count is |
* @throws IndexOutOfBoundsException if offset or count is incorrect |
301 |
* incorrect. |
* @throws UnsupportedEncodingException if encoding is not found |
302 |
* @exception UnsupportedEncodingException if the specified encoding is not |
* @throws Error if the decoding fails |
303 |
* found. |
* @since 1.1 |
304 |
*/ |
*/ |
305 |
public String(byte[] data, int offset, int count, String encoding) |
public String(byte[] data, int offset, int count, String encoding) |
306 |
throws NullPointerException, IndexOutOfBoundsException, |
throws UnsupportedEncodingException |
307 |
UnsupportedEncodingException { |
{ |
308 |
if (offset < 0 || count < 0 || offset+count > data.length) |
// XXX Sun checks encoding for null, then checks negative bounds, then |
309 |
|
// checks data for null, and finally searches for encoding. |
310 |
|
if (offset < 0 || count < 0 || offset + count > data.length) |
311 |
throw new StringIndexOutOfBoundsException(); |
throw new StringIndexOutOfBoundsException(); |
312 |
try { |
try |
313 |
value = EncodingManager.getDecoder(encoding).convertToChars(data, offset, |
{ |
314 |
count); |
value = EncodingManager.getDecoder(encoding) |
315 |
} catch (CharConversionException cce) { |
.convertToChars(data, offset, count); |
|
try { |
|
|
value = EncodingManager.getDecoder("8859_1").convertToChars(data, offset, |
|
|
count); |
|
|
} catch (IOException ioe) { |
|
|
throw new Error(ioe.toString()); |
|
316 |
} |
} |
317 |
} |
catch (CharConversionException cce) |
318 |
this.count = value.length; |
{ |
319 |
} |
throw new Error(cce); |
|
|
|
|
public String(byte[] data, int offset, int count) |
|
|
throws NullPointerException, IndexOutOfBoundsException { |
|
|
if (offset < 0 || count < 0 || offset+count > data.length) |
|
|
throw new StringIndexOutOfBoundsException(); |
|
|
try { |
|
|
value = EncodingManager.getDecoder().convertToChars(data, offset, count); |
|
|
} catch (CharConversionException cce) { |
|
|
try { |
|
|
value = EncodingManager.getDecoder("8859_1").convertToChars(data, offset, |
|
|
count); |
|
|
} catch (IOException ioe) { |
|
|
throw new Error(ioe.toString()); |
|
320 |
} |
} |
|
} |
|
321 |
this.count = value.length; |
this.count = value.length; |
322 |
} |
} |
323 |
|
|
324 |
/** |
/** |
325 |
* Creates a new String using an 8-bit array of integer values. |
* Creates a new String using the byte array. Uses the specified encoding |
326 |
* Each character `c', using corresponding byte `b', is created |
* type to decode the byte array, so the resulting string may be longer or |
327 |
* in the new String by performing: |
* shorter than the byte array. For more decoding control, use |
328 |
* |
* {@link java.nio.charset.CharsetDecoder}, and for valid character sets, |
329 |
* <pre> |
* see {@link java.nio.charset.Charset}. The behavior is not specified if |
330 |
* c = (char) (((hibyte & 0xff) << 8) | (b & 0xff)) |
* the decoder encounters invalid characters; this implementation throws |
331 |
* </pre> |
* an Error. |
332 |
* |
* |
333 |
* @param ascii array of integer values |
* @param data byte array to copy |
334 |
* @param hibyte top byte of each Unicode character |
* @param encoding the name of the encoding to use |
335 |
* |
* @throws NullPointerException if data or encoding is null |
336 |
* @exception NullPointerException if `ascii' is null |
* @throws UnsupportedEncodingException if encoding is not found |
337 |
* |
* @throws Error if the decoding fails |
338 |
* @deprecated Use constructors with byte to char decoders. |
* @see #String(byte[], int, int, String) |
339 |
|
* @since 1.1 |
340 |
*/ |
*/ |
341 |
public String(byte[] ascii, int hibyte) throws NullPointerException { |
public String(byte[] data, String encoding) |
342 |
count = ascii.length; |
throws UnsupportedEncodingException |
343 |
value = new char[count]; |
{ |
344 |
for (int i = 0; i < count; i++) |
this(data, 0, data.length, encoding); |
|
value[i] = (char) (((hibyte & 0xff) << 8) | (ascii[i] & 0xff)); |
|
345 |
} |
} |
346 |
|
|
347 |
/** |
/** |
348 |
* Creates a new String using an 8-bit array of integer values, |
* Creates a new String using the portion of the byte array starting at the |
349 |
* starting at an offset, and copying up to the count. |
* offset and ending at offset + count. Uses the encoding of the platform's |
350 |
* Each character `c', using corresponding byte `b', is created |
* default charset, so the resulting string may be longer or shorter than |
351 |
* in the new String by performing: |
* the byte array. For more decoding control, use |
352 |
* |
* {@link java.nio.charset.CharsetDecoder}. The behavior is not specified |
353 |
* <pre> |
* if the decoder encounters invalid characters; this implementation throws |
354 |
* c = (char) (((hibyte & 0xff) << 8) | (b & 0xff)) |
* an Error. |
|
* </pre> |
|
|
* |
|
|
* @param ascii array of integer values |
|
|
* @param hibyte top byte of each Unicode character |
|
|
* @param offset position (base 0) to start copying out of `ascii' |
|
|
* @param count the number of characters from `ascii' to copy |
|
|
* |
|
|
* @exception NullPointerException if `ascii' is null |
|
|
* @exception StringIndexOutOfBoundsException |
|
|
* if (offset < 0 || count < 0 || offset+count > ascii.length) |
|
355 |
* |
* |
356 |
* @deprecated Use constructors with byte to char decoders. |
* @param data byte array to copy |
357 |
|
* @param offset the offset to start at |
358 |
|
* @param count the number of characters in the array to use |
359 |
|
* @throws NullPointerException if data is null |
360 |
|
* @throws IndexOutOfBoundsException if offset or count is incorrect |
361 |
|
* @throws Error if the decoding fails |
362 |
|
* @see #String(byte[], int, int, String) |
363 |
|
* @since 1.1 |
364 |
*/ |
*/ |
365 |
public String(byte[] ascii, int hibyte, int offset, int count) |
public String(byte[] data, int offset, int count) |
366 |
throws NullPointerException, IndexOutOfBoundsException { |
{ |
367 |
if (offset < 0 || count < 0 || offset+count > ascii.length) |
if (offset < 0 || count < 0 || offset + count > data.length) |
368 |
throw new StringIndexOutOfBoundsException(); |
throw new StringIndexOutOfBoundsException(); |
369 |
this.count = count; |
try |
370 |
value = new char[count]; |
{ |
371 |
for (int i = 0; i < count; i++) |
value = EncodingManager.getDecoder() |
372 |
value[i] = (char) (((hibyte & 0xff) << 8) | (ascii[i+offset] & 0xff)); |
.convertToChars(data, offset, count); |
373 |
|
} |
374 |
|
catch (CharConversionException cce) |
375 |
|
{ |
376 |
|
throw new Error(cce); |
377 |
|
} |
378 |
|
this.count = value.length; |
379 |
} |
} |
380 |
|
|
381 |
/** |
/** |
382 |
* Special constructor used by StringBuffer, which results |
* Creates a new String using the byte array. Uses the encoding of the |
383 |
* in a new String which shares memory with a StringBuffer. |
* platform's default charset, so the resulting string may be longer or |
384 |
|
* shorter than the byte array. For more decoding control, use |
385 |
|
* {@link java.nio.charset.CharsetDecoder}. The behavior is not specified |
386 |
|
* if the decoder encounters invalid characters; this implementation throws |
387 |
|
* an Error. |
388 |
* |
* |
389 |
* @param data internal pointer to StringBuffer character data |
* @param data byte array to copy |
390 |
* @param length number of characters in `data' (data.length is the |
* @throws NullPointerException if data is null |
391 |
* capacity of the StringBuffer) |
* @throws Error if the decoding fails |
392 |
*/ |
* @see #String(byte[], int, int) |
393 |
String(char[] data, int length) { |
* @see #String(byte[], int, int, String) |
394 |
value = data; |
* @since 1.1 |
|
count = length; |
|
|
} |
|
|
|
|
|
/** |
|
|
* Returns `this'. |
|
395 |
*/ |
*/ |
396 |
public String toString() { |
public String(byte[] data) |
397 |
return this; |
{ |
398 |
|
this(data, 0, data.length); |
399 |
} |
} |
400 |
|
|
401 |
/** |
/** |
402 |
* Predicate which compares anObject to this. |
* Creates a new String using the character sequence represented by |
403 |
|
* the StringBuffer. Subsequent changes to buf do not affect the String. |
404 |
* |
* |
405 |
* @return true if anObject is a String and contains the |
* @param buf StringBuffer to copy |
406 |
* same character sequence as this String, else false |
* @throws NullPointerException if buf is null |
407 |
*/ |
*/ |
408 |
public boolean equals(Object anObject) { |
public String(StringBuffer buf) |
409 |
if (anObject == null) return false; |
{ |
410 |
if (!(anObject instanceof String)) return false; |
// XXX Synchronize on buf. |
411 |
String str2 = (String) anObject; |
count = buf.length(); |
412 |
if (count != str2.count) return false; |
value = new char[count]; |
413 |
for (int i = 0; i < count; i++) |
buf.getChars(0, buf.length(), value, 0); |
|
if (value[i] != str2.value[i]) return false; |
|
|
return true; |
|
414 |
} |
} |
415 |
|
|
416 |
/** |
/** |
417 |
* Compares the given StringBuffer to this String. |
* Special constructor used when data can safely be shared, rather than |
418 |
* |
* cloning it now (such as from StringBuffer). |
|
* @return true if the given StringBuffer has the same character |
|
|
* sequence as this String, else false |
|
|
* @exception NullPointerException if the given StringBuffer is null |
|
419 |
* |
* |
420 |
* @since 1.4 |
* @param data the characters, not modifiable by users, non-null |
421 |
|
* @param length number of characters in data |
422 |
*/ |
*/ |
423 |
public boolean contentEquals(StringBuffer buffer) { |
String(char[] data, int length) |
424 |
if (count != buffer.count) return false; |
{ |
425 |
for (int i = 0; i < count; i++) |
value = data; |
426 |
if (value[i] != buffer.value[i]) return false; |
count = length; |
|
return true; |
|
427 |
} |
} |
428 |
|
|
429 |
/** |
/** |
|
* Computes the hashcode for this String, according to JLS, Appendix D. |
|
|
* |
|
|
* @return hashcode value of this String |
|
|
*/ |
|
|
public int hashCode() { |
|
|
if (cachedHashCode != 0) return cachedHashCode; |
|
|
|
|
|
/* compute the hash code using a local variable such that we're |
|
|
reentrant */ |
|
|
int hashCode = 0; |
|
|
for (int i = 0; i < count; i++) |
|
|
hashCode = hashCode * 31 + value[i]; |
|
|
|
|
|
cachedHashCode = hashCode; |
|
|
return hashCode; |
|
|
} |
|
|
|
|
|
/** |
|
430 |
* Returns the number of characters contained in this String. |
* Returns the number of characters contained in this String. |
431 |
* |
* |
432 |
* @return the length of this String. |
* @return the length of this String |
433 |
*/ |
*/ |
434 |
public int length() { |
public int length() |
435 |
|
{ |
436 |
return count; |
return count; |
437 |
} |
} |
438 |
|
|
439 |
/** |
/** |
440 |
* Returns the character located at the specified index within |
* Returns the character located at the specified index within this String. |
|
* this String. |
|
441 |
* |
* |
442 |
* @param index position of character to return (base 0) |
* @param index position of character to return (base 0) |
443 |
* |
* @return character located at position index |
444 |
* @return character located at position `index' |
* @throws IndexOutOfBoundsException if index < 0 || index >= length() |
445 |
* |
* (while unspecified, this is a StringIndexOutOfBoundsException) |
|
* @exception StringIndexOutOfBoundsException |
|
|
* if (index < 0 || index >= this.length()) |
|
446 |
*/ |
*/ |
447 |
public char charAt(int index) throws IndexOutOfBoundsException { |
public char charAt(int index) |
448 |
if (index < 0 || index >= count) |
{ |
449 |
|
if (index < 0 || index >= count) |
450 |
throw new StringIndexOutOfBoundsException(index); |
throw new StringIndexOutOfBoundsException(index); |
451 |
return value[index]; |
return value[index]; |
452 |
} |
} |
459 |
* @param srcBegin index to begin copying characters from this String |
* @param srcBegin index to begin copying characters from this String |
460 |
* @param srcEnd index after the last character to be copied from this String |
* @param srcEnd index after the last character to be copied from this String |
461 |
* @param dst character array which this String is copied into |
* @param dst character array which this String is copied into |
462 |
* @param dstBegin index to start writing characters into `dst' |
* @param dstBegin index to start writing characters into dst |
463 |
* |
* @throws NullPointerException if dst is null |
464 |
* @exception NullPointerException if `dst' is null |
* @throws IndexOutOfBoundsException if any indices are out of bounds |
465 |
* @exception StringIndexOutOfBoundsException |
* (while unspecified, this is a StringIndexOutOfBoundsException) |
|
* if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > this.length() || |
|
|
* dstBegin < 0 || dstBegin+(srcEnd-srcBegin) > dst.length) |
|
466 |
*/ |
*/ |
467 |
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) |
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) |
468 |
throws NullPointerException, IndexOutOfBoundsException { |
{ |
469 |
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count || |
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count |
470 |
dstBegin < 0 || dstBegin+(srcEnd-srcBegin) > dst.length) |
|| dstBegin < 0 || dstBegin + srcEnd - srcBegin > dst.length) |
471 |
throw new StringIndexOutOfBoundsException(); |
throw new StringIndexOutOfBoundsException(); |
472 |
|
// XXX System.arraycopy this. |
473 |
for (int i = srcBegin; i < srcEnd; i++) |
for (int i = srcBegin; i < srcEnd; i++) |
474 |
dst[dstBegin + i - srcBegin] = value[i]; |
dst[dstBegin + i - srcBegin] = value[i]; |
475 |
} |
} |
476 |
|
|
477 |
/** |
/** |
478 |
* Copies the low byte of each character from this String starting |
* Copies the low byte of each character from this String starting at a |
479 |
* at a specified start index, ending at a specified stop index, to |
* specified start index, ending at a specified stop index, to a byte array |
480 |
* a byte array starting at a specified destination begin index. |
* starting at a specified destination begin index. |
481 |
* |
* |
482 |
* @param srcBegin index to being copying characters from this String |
* @param srcBegin index to being copying characters from this String |
483 |
* @param srcEnd index after the last character to be copied from this String |
* @param srcEnd index after the last character to be copied from this String |
484 |
* @param dst byte array which each low byte of this String is copied into |
* @param dst byte array which each low byte of this String is copied into |
485 |
* @param dstBegin index to start writing characters into `dst' |
* @param dstBegin index to start writing characters into dst |
486 |
* |
* @throws NullPointerException if dst is null |
487 |
* @exception NullPointerException if `dst' is null |
* @throws IndexOutOfBoundsException if any indices are out of bounds |
488 |
* @exception StringIndexOutOfBoundsException |
* (while unspecified, this is a StringIndexOutOfBoundsException) |
489 |
* if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > this.length() || |
* @see #getBytes() |
490 |
* dstBegin < 0 || dstBegin+(srcEnd-srcBegin) > dst.length) |
* @see #getBytes(String) |
491 |
* |
* @deprecated use {@link #getBytes()}, which uses a char to byte encoder |
|
* @deprecated Use a getBytes() which uses a char to byte encoder. |
|
492 |
*/ |
*/ |
493 |
public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) |
public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) |
494 |
throws NullPointerException, IndexOutOfBoundsException { |
{ |
495 |
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count || |
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count || |
496 |
dstBegin < 0 || dstBegin+(srcEnd-srcBegin) > dst.length) |
dstBegin < 0 || dstBegin + srcEnd - srcBegin > dst.length) |
497 |
throw new StringIndexOutOfBoundsException(); |
throw new StringIndexOutOfBoundsException(); |
498 |
for (int i = srcBegin; i < srcEnd; i++) |
for (int i = srcBegin; i < srcEnd; i++) |
499 |
dst[dstBegin + i - srcBegin] = (byte) value[i]; |
dst[dstBegin + i - srcBegin] = (byte) value[i]; |
500 |
} |
} |
501 |
|
|
502 |
/** |
/** |
503 |
* Converts the Unicode characters in this String to a byte stream |
* Converts the Unicode characters in this String to a byte array. Uses the |
504 |
* using a specified encoding method. |
* specified encoding method, so the result may be longer or shorter than |
505 |
|
* the String. For more encoding control, use |
506 |
|
* {@link java.nio.charset.CharsetEncoder}, and for valid character sets, |
507 |
|
* see {@link java.nio.charset.Charset}. The behavior is not specified if |
508 |
|
* the encoder encounters a problem; this implementation returns null. |
509 |
* |
* |
510 |
* @param enc encoding name |
* @param enc encoding name |
511 |
|
* @return the resulting byte array, or null on a problem |
512 |
|
* @throws NullPointerException if enc is null |
513 |
|
* @throws UnsupportedEncodingException if encoding is not supported |
514 |
|
* @since 1.1 |
515 |
|
*/ |
516 |
|
public byte[] getBytes(String enc) throws UnsupportedEncodingException |
517 |
|
{ |
518 |
|
try |
519 |
|
{ |
520 |
|
return EncodingManager.getEncoder(enc) |
521 |
|
.convertToBytes(value, offset, count); |
522 |
|
} |
523 |
|
catch (CharConversionException e) |
524 |
|
{ |
525 |
|
return null; |
526 |
|
} |
527 |
|
} |
528 |
|
|
529 |
|
/** |
530 |
|
* Converts the Unicode characters in this String to a byte array. Uses the |
531 |
|
* encoding of the platform's default charset, so the result may be longer |
532 |
|
* or shorter than the String. For more encoding control, use |
533 |
|
* {@link java.nio.charset.CharsetEncoder}. The behavior is not specified if |
534 |
|
* the encoder encounters a problem; this implementation returns null. |
535 |
* |
* |
536 |
* @return byte array representing the characters in this String using |
* @param enc encoding name |
537 |
* enc encoding, or null if the encoding fails |
* @return the resulting byte array, or null on a problem |
538 |
* |
* @throws NullPointerException if enc is null |
539 |
* @exception UnsupportedEncodingException if encoding is not supported |
* @throws UnsupportedEncodingException if encoding is not supported |
540 |
|
* @since 1.1 |
541 |
*/ |
*/ |
542 |
public byte[] getBytes(String enc) throws UnsupportedEncodingException { |
public byte[] getBytes() |
543 |
try { |
{ |
544 |
return EncodingManager.getEncoder(enc).convertToBytes(value, offset, count); |
try |
545 |
} catch (CharConversionException e) { |
{ |
546 |
return null; |
return EncodingManager.getEncoder() |
547 |
} |
.convertToBytes(value, offset, count); |
548 |
|
} |
549 |
|
catch (CharConversionException e) |
550 |
|
{ |
551 |
|
return null; |
552 |
|
} |
553 |
} |
} |
554 |
|
|
555 |
/** |
/** |
556 |
* Converts the Unicode characters in this String to a byte stream |
* Predicate which compares anObject to this. This is true only for Strings |
557 |
* using the system's default encoding method. |
* with the same character sequence. |
558 |
* |
* |
559 |
* @return byte array representing the characters in this String using |
* @param anObject the object to compare |
560 |
* the default encoding, or null if the encoding fails |
* @return true if anObject is semantically equal to this |
561 |
|
* @see #compareTo(String) |
562 |
|
* @see #equalsIgnoreCase(String) |
563 |
*/ |
*/ |
564 |
public byte[] getBytes() { |
public boolean equals(Object anObject) |
565 |
try { |
{ |
566 |
return EncodingManager.getEncoder().convertToBytes(value, offset, count); |
if (! (anObject instanceof String)) |
567 |
} catch (CharConversionException e) { |
return false; |
568 |
return null; |
String str2 = (String) anObject; |
569 |
} |
if (count != str2.count) |
570 |
} |
return false; |
571 |
|
for (int i = 0; i < count; i++) |
572 |
|
if (value[i] != str2.value[i]) |
573 |
|
return false; |
574 |
|
return true; |
575 |
|
} |
576 |
|
|
577 |
/** |
/** |
578 |
* Copies the contents of this String into a character array. |
* Compares the given StringBuffer to this String. This is true if the |
579 |
|
* StringBuffer has the same content as this String at this moment. |
580 |
* |
* |
581 |
* @return character array containing the same character sequence as |
* @param buffer the StringBuffer to compare to |
582 |
* this String. |
* @return true if StringBuffer has the same character sequence |
583 |
|
* @throws NullPointerException if the given StringBuffer is null |
584 |
|
* @since 1.4 |
585 |
*/ |
*/ |
586 |
public char[] toCharArray() { |
public boolean contentEquals(StringBuffer buffer) |
587 |
char[] copy = new char[count]; |
{ |
588 |
if (value.length != count) |
// XXX Synchronize on buffer. |
589 |
System.err.println("value.length=" + value.length + " count=" + count); |
if (count != buffer.count) |
590 |
System.arraycopy(value, 0, copy, 0, count); |
return false; |
591 |
return copy; |
for (int i = 0; i < count; i++) |
592 |
|
if (value[i] != buffer.value[i]) |
593 |
|
return false; |
594 |
|
return true; |
595 |
} |
} |
596 |
|
|
597 |
/** |
/** |
598 |
* Compares a String to this String, ignoring case. |
* Compares a String to this String, ignoring case. This does not handle |
599 |
|
* multi-character capitalization exceptions; instead the comparison is |
600 |
|
* made on a character-by-character basis, and is true if:<br><ul> |
601 |
|
* <li><code>c1 == c2</code></li> |
602 |
|
* <li><code>Character.toUpperCase(c1) |
603 |
|
* == Character.toUpperCase(c2)</code></li> |
604 |
|
* <li><code>Character.toLowerCase(c1) |
605 |
|
* == Character.toLowerCase(c2)</code></li> |
606 |
|
* </ul> |
607 |
* |
* |
608 |
* @param anotherString String to compare to this String |
* @param anotherString String to compare to this String |
609 |
* |
* @return true if anotherString is equal, ignoring case |
610 |
* @return true if `anotherString' and this String have the same |
* @see #equals(Object) |
611 |
* character sequence, ignoring case, else false. |
* @see Character#toUpperCase(char) |
612 |
|
* @see Character#toLowerCase(char) |
613 |
*/ |
*/ |
614 |
public boolean equalsIgnoreCase(String anotherString) { |
public boolean equalsIgnoreCase(String anotherString) |
615 |
|
{ |
616 |
if (anotherString == null || count != anotherString.count) |
if (anotherString == null || count != anotherString.count) |
617 |
return false; |
return false; |
618 |
for (int i = 0; i < count; i++) |
for (int i = 0; i < count; i++) |
619 |
if (value[i] == anotherString.value[i] || |
// Note that checking c1 != c2 is redundant, but avoids method calls. |
620 |
Character.toUpperCase(value[i]) == Character.toUpperCase(anotherString.value[i]) || |
if (value[i] != anotherString.value[i] |
621 |
Character.toLowerCase(value[i]) == Character.toLowerCase(anotherString.value[i])) |
&& (Character.toUpperCase(value[i]) |
622 |
continue; |
!= Character.toUpperCase(anotherString.value[i])) |
623 |
else |
&& (Character.toLowerCase(value[i]) |
624 |
return false; |
!= Character.toLowerCase(anotherString.value[i]))) |
625 |
|
return false; |
626 |
return true; |
return true; |
627 |
} |
} |
628 |
|
|
629 |
/** |
/** |
630 |
* Compares this String and another String (case sensitive). |
* Compares this String and another String (case sensitive, |
631 |
* |
* lexicographically). The result is less than 0 if this string sorts |
632 |
* @return returns an integer less than, equal to, or greater than |
* before the other, 0 if they are equal, and greater than 0 otherwise. |
633 |
* zero, if this String is found, respectively, to be less than, |
* After any common starting sequence is skipped, the result is |
634 |
* to match, or be greater than `anotherString'. |
* <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings |
635 |
|
* have characters remaining, or |
636 |
|
* <code>this.length() - anotherString.length()</code> if one string is |
637 |
|
* a subsequence of the other. |
638 |
|
* |
639 |
|
* @param anotherString the String to compare against |
640 |
|
* @return the comparison |
641 |
|
* @throws NullPointerException if anotherString is null |
642 |
*/ |
*/ |
643 |
public int compareTo(String anotherString) throws NullPointerException { |
public int compareTo(String anotherString) |
644 |
|
{ |
645 |
int min = Math.min(count, anotherString.count); |
int min = Math.min(count, anotherString.count); |
646 |
for (int i = 0; i < min; i++) { |
for (int i = 0; i < min; i++) |
647 |
int result = value[i]-anotherString.value[i]; |
{ |
648 |
if (result != 0) |
int result = value[i] - anotherString.value[i]; |
649 |
return result; |
if (result != 0) |
650 |
} |
return result; |
651 |
return count-anotherString.count; |
} |
652 |
|
return count - anotherString.count; |
653 |
} |
} |
654 |
|
|
655 |
/** |
/** |
656 |
* Behaves like <code>compareTo(java.lang.String)</code> unless the Object |
* Behaves like <code>compareTo(java.lang.String)</code> unless the Object |
657 |
* is not a <code>String</code>. Then it throws a |
* is not a <code>String</code>. Then it throws a |
658 |
* <code>ClassCastException</code>. |
* <code>ClassCastException</code>. |
|
* @exception ClassCastException if the argument is not a |
|
|
* <code>String</code>. |
|
659 |
* |
* |
660 |
|
* @param anotherString the object to compare against |
661 |
|
* @return the comparison |
662 |
|
* @throws NullPointerException if anotherString is null |
663 |
|
* @throws ClassCastException if the argument is not a <code>String</code> |
664 |
* @since 1.2 |
* @since 1.2 |
665 |
*/ |
*/ |
666 |
public int compareTo(Object o) |
public int compareTo(Object o) |
667 |
{ |
{ |
668 |
return compareTo((String)o); |
return compareTo((String) o); |
669 |
} |
} |
670 |
|
|
671 |
/** |
/** |
672 |
* Compares this String and another String (case insensitive). |
* Compares this String and another String (case insensitive). This |
673 |
* |
* comparison is <em>different</em> from equalsIgnoreCase, in that it uses |
674 |
* @return returns an integer less than, equal to, or greater than |
* <code>this.toUpperCase().toLowerCase() |
675 |
* zero, if this String is found, respectively, to be less than, |
* .compareTo(s.toUpperCase().toLowerCase())</code>, which can perform |
676 |
* to match, or be greater than the given String. |
* multi-character capitalization expansions. However, this is still |
677 |
|
* unsatisfactory for certain locales, in which case you should use |
678 |
|
* {@link java.text.Collator}. |
679 |
* |
* |
680 |
|
* @param s the string to compare against |
681 |
|
* @return the comparison |
682 |
|
* @see Collator#compare(String, String) |
683 |
* @since 1.2 |
* @since 1.2 |
684 |
*/ |
*/ |
685 |
public int compareToIgnoreCase(String s) |
public int compareToIgnoreCase(String s) |
686 |
{ |
{ |
687 |
int min = Math.min(count, s.count); |
return toUpperCase().toLowerCase().compareTo(s.toUpperCase() |
688 |
for (int i = 0; i < min; i++) |
.toLowerCase()); |
|
{ |
|
|
char c1 = Character.toLowerCase(Character.toUpperCase(value[i])); |
|
|
char c2 = Character.toLowerCase(Character.toUpperCase(s.value[i])); |
|
|
int result = c1 - c2; |
|
|
if (result != 0) |
|
|
return result; |
|
|
} |
|
|
return count-s.count; |
|
689 |
} |
} |
690 |
|
|
691 |
/** |
/** |
692 |
* Predicate which determines if this String matches another String |
* Predicate which determines if this String matches another String |
693 |
* starting at a specified offset for each String and continuing |
* starting at a specified offset for each String and continuing |
694 |
* for a specified length. |
* for a specified length. Indices out of bounds are harmless, and give |
695 |
|
* a false result. |
696 |
* |
* |
697 |
* @param toffset index to start comparison at for this String |
* @param toffset index to start comparison at for this String |
698 |
* @param other String to compare region to this String |
* @param other String to compare region to this String |
699 |
* @param oofset index to start comparison at for `other' |
* @param oofset index to start comparison at for other |
700 |
* @param len number of characters to compare |
* @param len number of characters to compare |
701 |
* |
* @return true if regions match (case sensitive) |
702 |
* @return true if regions match (case sensitive), false otherwise. |
* @throws NullPointerException if other is null |
|
* |
|
|
* @exception NullPointerException if `other' is null |
|
703 |
*/ |
*/ |
704 |
public boolean regionMatches(int toffset, String other, int ooffset, |
public boolean regionMatches(int toffset, String other, int ooffset, int len) |
705 |
int len) |
{ |
|
throws NullPointerException { |
|
706 |
return regionMatches(false, toffset, other, ooffset, len); |
return regionMatches(false, toffset, other, ooffset, len); |
707 |
} |
} |
708 |
|
|
709 |
/** |
/** |
710 |
* Predicate which determines if this String matches another String |
* Predicate which determines if this String matches another String |
711 |
* starting at a specified offset for each String and continuing for |
* starting at a specified offset for each String and continuing |
712 |
* a specified length, optionally ignoring case. |
* for a specified length, optionally ignoring case. Indices out of bounds |
713 |
|
* are harmless, and give a false result. Case comparisons are based on |
714 |
|
* <code>Character.toLowerCase()</code> and |
715 |
|
* <code>Character.toUpperCase()</code>, not on multi-character |
716 |
|
* capitalization expansions. |
717 |
* |
* |
718 |
* @param ignoreCase true if case should be ignored in comparision |
* @param ignoreCase true if case should be ignored in comparision |
719 |
* @param toffset index to start comparison at for this String |
* @param toffset index to start comparison at for this String |
720 |
* @param other String to compare region to this String |
* @param other String to compare region to this String |
721 |
* @param oofset index to start comparison at for `other' |
* @param oofset index to start comparison at for other |
722 |
* @param len number of characters to compare |
* @param len number of characters to compare |
723 |
* |
* @return true if regions match, false otherwise |
724 |
* @return true if regions match, false otherwise. |
* @throws NullPointerException if other is null |
|
* |
|
|
* @exception NullPointerException if `other' is null |
|
725 |
*/ |
*/ |
726 |
public boolean regionMatches(boolean ignoreCase, int toffset, String other, |
public boolean regionMatches(boolean ignoreCase, int toffset, |
727 |
int ooffset, int len) |
String other, int ooffset, int len) |
728 |
throws NullPointerException { |
{ |
729 |
if (toffset < 0 || ooffset < 0 || toffset+len > count || |
if (toffset < 0 || ooffset < 0 || toffset + len > count || |
730 |
ooffset+len > other.count) |
ooffset + len > other.count) |
731 |
return false; |
return false; |
732 |
for (int i = 0; i < len; i++) |
for (int i = 0; i < len; i++) |
733 |
if (ignoreCase) |
// Note that checking c1 != c2 is redundant when ignoreCase is true, |
734 |
if (value[toffset+i] == other.value[ooffset+i] || |
// but it avoids method calls. |
735 |
Character.toLowerCase(value[toffset+i]) == |
if (value[toffset + i] != other.value[ooffset + i] |
736 |
Character.toLowerCase(other.value[ooffset+i]) || |
&& (! ignoreCase |
737 |
Character.toUpperCase(value[toffset+i]) == |
|| ((Character.toLowerCase(value[toffset + i]) |
738 |
Character.toUpperCase(other.value[ooffset+i])) |
!= Character.toLowerCase(other.value[ooffset + i])) |
739 |
continue; |
&& (Character.toUpperCase(value[toffset + i]) |
740 |
else |
!= Character.toUpperCase(other.value[ooffset + i]))))) |
741 |
return false; |
return false; |
|
else |
|
|
if (value[toffset+i] != other.value[ooffset+i]) |
|
|
return false; |
|
742 |
return true; |
return true; |
743 |
} |
} |
744 |
|
|
745 |
/** |
/** |
746 |
* Predicate which determines if this String starts with a given prefix. |
* Predicate which determines if this String contains the given prefix, |
747 |
* If the prefix is an empty String, true is returned. |
* beginning comparison at toffset. The result is false if toffset is |
748 |
* |
* negative or greater than this.length(), otherwise it is the same as |
749 |
* @param prefex String to compare |
* <code>this.subString(toffset).startsWith(prefix)</code>. |
750 |
* |
* |
751 |
* @return true if this String starts with the character sequence |
* @param prefix String to compare |
752 |
* represented by `prefix', else false. |
* @param toffset offset for this String where comparison starts |
753 |
* |
* @return true if this String starts with prefix |
754 |
* @exception NullPointerException if `prefix' is null |
* @throws NullPointerException if prefix is null |
755 |
|
* @see #regionMatches(boolean, int, String, int, int) |
756 |
*/ |
*/ |
757 |
public boolean startsWith(String prefix) throws NullPointerException { |
public boolean startsWith(String prefix, int toffset) |
758 |
return (prefix.count == 0) ? true : |
{ |
759 |
regionMatches(0, prefix, 0, prefix.count); |
if (toffset < 0 || toffset > count) |
760 |
|
return false; |
761 |
|
return prefix.count == 0 |
762 |
|
|| regionMatches(toffset, prefix, 0, prefix.count); |
763 |
} |
} |
764 |
|
|
765 |
/** |
/** |
766 |
* Predicate which determines if this String starts with a given |
* Predicate which determines if this String starts with a given prefix. |
|
* prefix, beginning comparison using offset of this String. |
|
767 |
* If the prefix is an empty String, true is returned. |
* If the prefix is an empty String, true is returned. |
768 |
* |
* |
769 |
* @param prefix String to compare |
* @param prefex String to compare |
770 |
* @param toffset offset for this String where comparison starts |
* @return true if this String starts with the prefix |
771 |
* |
* @throws NullPointerException if prefix is null |
772 |
* @return true if this String starts with the character sequence |
* @see #startsWith(String, int) |
|
* represented by prefix, else false. |
|
|
* |
|
|
* @exception NullPointerException if `prefix' is null |
|
773 |
*/ |
*/ |
774 |
public boolean startsWith(String prefix, int toffset) |
public boolean startsWith(String prefix) |
775 |
throws NullPointerException { |
{ |
776 |
if (toffset < 0 || toffset > count) return false; |
return prefix.count == 0 |
777 |
return (prefix.count == 0) ? true : |
|| regionMatches(0, prefix, 0, prefix.count); |
|
regionMatches(toffset, prefix, 0, prefix.count); |
|
778 |
} |
} |
779 |
|
|
780 |
/** |
/** |
781 |
* Predicate which determines if this String ends with a given suffix. |
* Predicate which determines if this String ends with a given suffix. |
782 |
* If the suffix is an empty String, true is returned. |
* If the suffix is an empty String, true is returned. |
783 |
* |
* |
784 |
* @param suffix String to compare |
* @param suffix String to compare |
785 |
|
* @return true if this String ends with the suffix |
786 |
|
* @throws NullPointerException if suffix is null |
787 |
|
* @see #regionMatches(boolean, int, String, int, int) |
788 |
|
*/ |
789 |
|
public boolean endsWith(String suffix) |
790 |
|
{ |
791 |
|
return suffix.count == 0 |
792 |
|
|| regionMatches(count - suffix.count, suffix, 0, suffix.count); |
793 |
|
} |
794 |
|
|
795 |
|
/** |
796 |
|
* Computes the hashcode for this String. This is done with int arithmetic, |
797 |
|
* where ** represents exponentiation, by this formula:<br> |
798 |
|
* <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>. |
799 |
* |
* |
800 |
* @return true if this String ends with the character sequence |
* @return hashcode value of this String |
|
* represented by prefix, else false. |
|
|
* |
|
|
* @exception NullPointerException if `suffix' is null |
|
801 |
*/ |
*/ |
802 |
public boolean endsWith(String suffix) throws NullPointerException { |
public int hashCode() |
803 |
return (suffix.count == 0) ? true : |
{ |
804 |
regionMatches(count-suffix.count, suffix, 0, suffix.count); |
if (cachedHashCode != 0) |
805 |
|
return cachedHashCode; |
806 |
|
|
807 |
|
// Compute the hash code using a local variable to be reentrant. |
808 |
|
int hashCode = 0; |
809 |
|
for (int i = 0; i < count; i++) |
810 |
|
hashCode = hashCode * 31 + value[i]; |
811 |
|
return cachedHashCode = hashCode; |
812 |
} |
} |
813 |
|
|
814 |
/** |
/** |
815 |
* Finds the first instance of a character in this String. |
* Finds the first instance of a character in this String. |
816 |
* |
* |
817 |
* @param ch character to find |
* @param ch character to find |
|
* |
|
818 |
* @return location (base 0) of the character, or -1 if not found |
* @return location (base 0) of the character, or -1 if not found |
819 |
*/ |
*/ |
820 |
public int indexOf(int ch) { |
public int indexOf(int ch) |
821 |
|
{ |
822 |
return indexOf(ch, 0); |
return indexOf(ch, 0); |
823 |
} |
} |
824 |
|
|
830 |
* |
* |
831 |
* @param ch character to find |
* @param ch character to find |
832 |
* @param fromIndex index to start the search |
* @param fromIndex index to start the search |
|
* |
|
833 |
* @return location (base 0) of the character, or -1 if not found |
* @return location (base 0) of the character, or -1 if not found |
834 |
*/ |
*/ |
835 |
public int indexOf(int ch, int fromIndex) { |
public int indexOf(int ch, int fromIndex) |
836 |
if (fromIndex < 0) fromIndex = 0; |
{ |
837 |
|
if (fromIndex < 0) |
838 |
|
fromIndex = 0; |
839 |
for (int i = fromIndex; i < count; i++) |
for (int i = fromIndex; i < count; i++) |
840 |
if (value[i] == ch) |
if (value[i] == ch) |
841 |
return i; |
return i; |
842 |
return -1; |
return -1; |
843 |
} |
} |
844 |
|
|
845 |
/** |
/** |
846 |
* Finds the first instance of a String in this String. |
* Finds the last instance of a character in this String. |
|
* |
|
|
* @param str String to find |
|
|
* |
|
|
* @return location (base 0) of the String, or -1 if not found |
|
847 |
* |
* |
848 |
* @exception NullPointerException if `str' is null |
* @param ch character to find |
849 |
|
* @return location (base 0) of the character, or -1 if not found |
850 |
*/ |
*/ |
851 |
public int indexOf(String str) throws NullPointerException { |
public int lastIndexOf(int ch) |
852 |
return indexOf(str, 0); |
{ |
853 |
|
return lastIndexOf(ch, count - 1); |
854 |
} |
} |
855 |
|
|
856 |
/** |
/** |
857 |
* Finds the first instance of a String in this String, starting at |
* Finds the last instance of a character in this String, starting at |
858 |
* a given index. If starting index is less than 0, the search |
* a given index. If starting index is greater than the maximum valid |
859 |
* starts at the beginning of this String. If the starting index |
* index, then the search begins at the end of this String. If the |
860 |
* is greater than the length of this String, -1 is returned. |
* starting index is less than zero, -1 is returned. |
861 |
* |
* |
862 |
* @param str String to find |
* @param ch character to find |
863 |
* @param fromIndex index to start the search |
* @param fromIndex index to start the search |
864 |
* |
* @return location (base 0) of the character, or -1 if not found |
|
* @return location (base 0) of the String, or -1 if not found |
|
|
* |
|
|
* @exception NullPointerException if `str' is null |
|
865 |
*/ |
*/ |
866 |
public int indexOf(String str, int fromIndex) throws NullPointerException { |
public int lastIndexOf(int ch, int fromIndex) |
867 |
if (fromIndex < 0) fromIndex = 0; |
{ |
868 |
for (int i = fromIndex; i <= count; i++) |
if (fromIndex >= count) |
869 |
if (regionMatches(i, str, 0, str.count)) |
fromIndex = count - 1; |
870 |
return i; |
for (int i = fromIndex; i >= 0; i--) |
871 |
|
if (value[i] == ch) |
872 |
|
return i; |
873 |
return -1; |
return -1; |
874 |
} |
} |
875 |
|
|
876 |
/** |
/** |
877 |
* Finds the last instance of a character in this String. |
* Finds the first instance of a String in this String. |
|
* |
|
|
* @param ch character to find |
|
878 |
* |
* |
879 |
* @return location (base 0) of the character, or -1 if not found |
* @param str String to find |
880 |
|
* @return location (base 0) of the String, or -1 if not found |
881 |
|
* @throws NullPointerException if str is null |
882 |
*/ |
*/ |
883 |
public int lastIndexOf(int ch) { |
public int indexOf(String str) |
884 |
return lastIndexOf(ch, count-1); |
{ |
885 |
|
return indexOf(str, 0); |
886 |
} |
} |
887 |
|
|
888 |
/** |
/** |
889 |
* Finds the last instance of a character in this String, starting at |
* Finds the first instance of a String in this String, starting at |
890 |
* a given index. If starting index is greater than the maximum valid |
* a given index. If starting index is less than 0, the search |
891 |
* index, then the search begins at the end of this String. If the |
* starts at the beginning of this String. If the starting index |
892 |
* starting index is less than zero, -1 is returned. |
* is greater than the length of this String, -1 is returned. |
893 |
* |
* |
894 |
* @param ch character to find |
* @param str String to find |
895 |
* @param fromIndex index to start the search |
* @param fromIndex index to start the search |
896 |
* |
* @return location (base 0) of the String, or -1 if not found |
897 |
* @return location (base 0) of the character, or -1 if not found |
* @throws NullPointerException if str is null |
898 |
*/ |
*/ |
899 |
public int lastIndexOf(int ch, int fromIndex) { |
public int indexOf(String str, int fromIndex) |
900 |
if (fromIndex >= count) |
{ |
901 |
fromIndex = count-1; |
if (fromIndex < 0) |
902 |
for (int i = fromIndex; i >= 0; i--) |
fromIndex = 0; |
903 |
if (value[i] == ch) |
for (int i = fromIndex; i <= count; i++) |
904 |
return i; |
if (regionMatches(i, str, 0, str.count)) |
905 |
|
return i; |
906 |
return -1; |
return -1; |
907 |
} |
} |
908 |
|
|
910 |
* Finds the last instance of a String in this String. |
* Finds the last instance of a String in this String. |
911 |
* |
* |
912 |
* @param str String to find |
* @param str String to find |
|
* |
|
913 |
* @return location (base 0) of the String, or -1 if not found |
* @return location (base 0) of the String, or -1 if not found |
914 |
* |
* @throws NullPointerException if str is null |
|
* @exception NullPointerException if `str' is null |
|
915 |
*/ |
*/ |
916 |
public int lastIndexOf(String str) throws NullPointerException { |
public int lastIndexOf(String str) |
917 |
return lastIndexOf(str, count-str.count); |
{ |
918 |
|
return lastIndexOf(str, count - str.count); |
919 |
} |
} |
920 |
|
|
921 |
/** |
/** |
922 |
* Finds the last instance of a String in this String, starting at |
* Finds the last instance of a String in this String, starting at |
923 |
* a given index. If starting index is greater than the maximum valid |
* a given index. If starting index is greater than the maximum valid |
924 |
* index, then the search begins at the end of this String. If the |
* index, then the search begins at the end of this String. If the |
925 |
* starting index is less than zero, -1 is returned. |
* starting index is less than zero, -1 is returned. |
926 |
* |
* |
927 |
* @param str String to find |
* @param str String to find |
928 |
* @param fromIndex index to start the search |
* @param fromIndex index to start the search |
|
* |
|
929 |
* @return location (base 0) of the String, or -1 if not found |
* @return location (base 0) of the String, or -1 if not found |
930 |
* |
* @throws NullPointerException if str is null |
|
* @exception NullPointerException if `str' is null |
|
931 |
*/ |
*/ |
932 |
public int lastIndexOf(String str, int fromIndex) |
public int lastIndexOf(String str, int fromIndex) |
933 |
throws NullPointerException { |
{ |
934 |
if (fromIndex >= count) |
if (fromIndex >= count) |
935 |
fromIndex = count - str.count; |
fromIndex = count - str.count; |
936 |
for (int i = fromIndex; i >= 0; i--) |
for (int i = fromIndex; i >= 0; i--) |
937 |
if (regionMatches(i, str, 0, str.count)) |
if (regionMatches(i, str, 0, str.count)) |
938 |
return i; |
return i; |
939 |
return -1; |
return -1; |
940 |
} |
} |
941 |
|
|
942 |
/** |
/** |
943 |
* Creates a substring of this String, starting at a specified index |
* Creates a substring of this String, starting at a specified index |
944 |
* and ending at the end of this String. |
* and ending at the end of this String. |
945 |
* |
* |
946 |
* @param beginIndex index to start substring (base 0) |
* @param begin index to start substring (base 0) |
|
* |
|
947 |
* @return new String which is a substring of this String |
* @return new String which is a substring of this String |
948 |
* |
* @throws IndexOutOfBoundsException if begin < 0 || begin > length() |
949 |
* @exception StringIndexOutOfBoundsException |
* (while unspecified, this is a StringIndexOutOfBoundsException) |
|
* if (beginIndex < 0 || beginIndex > this.length()) |
|
950 |
*/ |
*/ |
951 |
public String substring(int beginIndex) throws IndexOutOfBoundsException { |
public String substring(int begin) |
952 |
return substring(beginIndex, count); |
{ |
953 |
|
return substring(begin, count); |
954 |
} |
} |
955 |
|
|
956 |
/** |
/** |
957 |
* Creates a substring of this String, starting at a specified index |
* Creates a substring of this String, starting at a specified index |
958 |
* and ending at one character before a specified index. |
* and ending at one character before a specified index. |
959 |
* |
* |
960 |
* @param beginIndex index to start substring (base 0) |
* @param begin index to start substring (inclusive, base 0) |
961 |
* @param endIndex index after the last character to be |
* @param end index to end at (exclusive) |
|
* copied into the substring |
|
|
* |
|
962 |
* @return new String which is a substring of this String |
* @return new String which is a substring of this String |
963 |
* |
* @throws IndexOutOfBoundsException if begin < 0 || end > length() |
964 |
* @exception StringIndexOutOfBoundsException |
* || begin > end (while unspecified, this is a |
965 |
* if (beginIndex < 0 || endIndex > this.length() || beginIndex > endIndex) |
* StringIndexOutOfBoundsException) |
966 |
*/ |
*/ |
967 |
public String substring(int beginIndex, int endIndex) |
public String substring(int beginIndex, int endIndex) |
968 |
throws IndexOutOfBoundsException { |
{ |
969 |
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) |
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) |
970 |
throw new StringIndexOutOfBoundsException(); |
throw new StringIndexOutOfBoundsException(); |
971 |
char[] newStr = new char[endIndex-beginIndex]; |
char[] newStr = new char[endIndex - beginIndex]; |
972 |
System.arraycopy(value, beginIndex, newStr, 0, endIndex-beginIndex); |
System.arraycopy(value, beginIndex, newStr, 0, endIndex - beginIndex); |
973 |
return new String(newStr); |
return new String(newStr); |
974 |
} |
} |
975 |
|
|
976 |
/** |
/** |
977 |
* Creates a substring of this String, starting at a specified index |
* Creates a substring of this String, starting at a specified index |
978 |
* and ending at one character before a specified index. |
* and ending at one character before a specified index. This behaves like |
979 |
* <p> |
* <code>substring(beginIndex, endIndex)</code>. |
|
* To implement <code>CharSequence</code>. |
|
|
* Calls <code>substring(beginIndex, endIndex)</code>. |
|
|
* |
|
|
* @param beginIndex index to start substring (base 0) |
|
|
* @param endIndex index after the last character to be |
|
|
* copied into the substring |
|
|
* |
|
|
* @return new String which is a substring of this String |
|
980 |
* |
* |
981 |
* @exception StringIndexOutOfBoundsException |
* @param beginIndex index to start substring (inclusive, base 0) |
982 |
* if (beginIndex < 0 || endIndex > this.length() || beginIndex > endIndex) |
* @param endIndex index to end at (exclusive) |
983 |
|
* @return new String which is a substring of this String |
984 |
|
* @throws IndexOutOfBoundsException if begin < 0 || end > length() |
985 |
|
* || begin > end |
986 |
|
* @since 1.4 |
987 |
*/ |
*/ |
988 |
public CharSequence subSequence(int beginIndex, int endIndex) |
public CharSequence subSequence(int beginIndex, int endIndex) |
989 |
throws IndexOutOfBoundsException { |
{ |
990 |
return substring(beginIndex, endIndex); |
return substring(beginIndex, endIndex); |
991 |
} |
} |
992 |
|
|
993 |
/** |
/** |
994 |
* Concatenates a String to this String. |
* Concatenates a String to this String. This results in a new string unless |
995 |
|
* one of the two originals is "". |
996 |
* |
* |
997 |
* @param str String to append to this String |
* @param str String to append to this String |
|
* |
|
998 |
* @return newly concatenated String |
* @return newly concatenated String |
999 |
* |
* @throws NullPointerException if str is null |
|
* @exception NullPointerException if `str' is null |
|
1000 |
*/ |
*/ |
1001 |
public String concat(String str) throws NullPointerException { |
public String concat(String str) |
1002 |
if (str.count == 0) return this; |
{ |
1003 |
|
if (str.count == 0) |
1004 |
|
return this; |
1005 |
char[] newStr = new char[count + str.count]; |
char[] newStr = new char[count + str.count]; |
1006 |
System.arraycopy(this.value, 0, newStr, 0, count); |
System.arraycopy(this.value, 0, newStr, 0, count); |
1007 |
System.arraycopy(str.value, 0, newStr, count, str.count); |
System.arraycopy(str.value, 0, newStr, count, str.count); |
1009 |
} |
} |
1010 |
|
|
1011 |
/** |
/** |
1012 |
* Replaces every instances of a character in this String with |
* Replaces every instance of a character in this String with a new |
1013 |
* a new character. |
* character. If no replacements occur, this is returned. |
1014 |
* |
* |
1015 |
* @param oldChar the old character to replace |
* @param oldChar the old character to replace |
1016 |
* @param newChar the new character to put in place of the old character |
* @param newChar the new character |
1017 |
* |
* @return new String with all instances of oldChar replaced with newChar |
|
* @return new String with all instances of `oldChar' replaced with `newChar' |
|
1018 |
*/ |
*/ |
1019 |
public String replace(char oldChar, char newChar) { |
public String replace(char oldChar, char newChar) |
1020 |
|
{ |
1021 |
int index = 0; |
int index = 0; |
1022 |
for (; index < count; index++) |
for (; index < count; index++) |
1023 |
if (value[index] == oldChar) |
if (value[index] == oldChar) |
1024 |
break; |
break; |
1025 |
if (index == count) return this; |
if (index == count) return this; |
1026 |
char[] newStr = new char[count]; |
char[] newStr = new char[count]; |
1027 |
System.arraycopy(value, 0, newStr, 0, count); |
System.arraycopy(value, 0, newStr, 0, count); |
1028 |
for (int i = index; i < count; i++) |
for (int i = index; i < count; i++) |
1029 |
if (value[i] == oldChar) |
if (value[i] == oldChar) |
1030 |
newStr[i] = newChar; |
newStr[i] = newChar; |
1031 |
return new String(newStr); |
return new String(newStr); |
1032 |
} |
} |
1033 |
|
|
1034 |
/** |
/** |
1035 |
* Lowercases this String. |
* Test if this String matches a regular expression. This is shorthand for |
1036 |
|
* <code>{@link Pattern}.matches(regex, this)</code>. |
1037 |
|
* |
1038 |
|
* @param regex the pattern to match |
1039 |
|
* @return true if the pattern matches |
1040 |
|
* @throws NullPointerException if regex is null |
1041 |
|
* @throws PatternSyntaxExceptions if regex is invalid |
1042 |
|
* @since 1.4 |
1043 |
|
* @XXX Add this method. |
1044 |
|
public boolean matches(String regex) |
1045 |
|
{ |
1046 |
|
return Pattern.matches(regex, this); |
1047 |
|
} |
1048 |
|
*/ |
1049 |
|
|
1050 |
|
/** |
1051 |
|
* Replaces the first substring match of the regular expression with a |
1052 |
|
* given replacement. This is shorthand for <code>{@link Pattern} |
1053 |
|
* .compile(regex).matcher(this).replaceFirst(replacement)</code>. |
1054 |
|
* |
1055 |
|
* @param regex the pattern to match |
1056 |
|
* @param replacement the replacement string |
1057 |
|
* @return the modified string |
1058 |
|
* @throws NullPointerException if regex or replacement is null |
1059 |
|
* @throws PatternSyntaxExceptions if regex is invalid |
1060 |
|
* @since 1.4 |
1061 |
|
* @XXX Add this method. |
1062 |
|
public String replaceFirst(String regex, String replacement) |
1063 |
|
{ |
1064 |
|
return Pattern.compile(regex).matcher(this).replaceFirst(replacement); |
1065 |
|
} |
1066 |
|
*/ |
1067 |
|
|
1068 |
|
/** |
1069 |
|
* Replaces all matching substrings of the regular expression with a |
1070 |
|
* given replacement. This is shorthand for <code>{@link Pattern} |
1071 |
|
* .compile(regex).matcher(this).replaceAll(replacement)</code>. |
1072 |
|
* |
1073 |
|
* @param regex the pattern to match |
1074 |
|
* @param replacement the replacement string |
1075 |
|
* @return the modified string |
1076 |
|
* @throws NullPointerException if regex or replacement is null |
1077 |
|
* @throws PatternSyntaxExceptions if regex is invalid |
1078 |
|
* @since 1.4 |
1079 |
|
* @XXX Add this method. |
1080 |
|
public String replaceAll(String regex, String replacement) |
1081 |
|
{ |
1082 |
|
return Pattern.compile(regex).matcher(this).replaceFirst(replacement); |
1083 |
|
} |
1084 |
|
*/ |
1085 |
|
|
1086 |
|
/** |
1087 |
|
* Split this string around the matches of a regular expression. Each |
1088 |
|
* element of the returned array is the largest block of characters not |
1089 |
|
* terminated by the regular expression, in the order the matches are found. |
1090 |
|
* |
1091 |
|
* <p>The limit affects the length of the array. If it is positive, the |
1092 |
|
* array will contain at most n elements (n - 1 pattern matches). If |
1093 |
|
* negative, the array length is unlimited, but there can be trailing empty |
1094 |
|
* entries. if 0, the array length is unlimited, and trailing empty entries |
1095 |
|
* are discarded. |
1096 |
|
* |
1097 |
|
* <p>For example, splitting "boo:and:foo" yields:<br> |
1098 |
|
* <table border=0> |
1099 |
|
* <th><td>Regex</td> <td>Limit</td> <td>Result</td></th> |
1100 |
|
* <tr><td>":"</td> <td>2</td> <td>{ "boo", "and:foo" }</td></tr> |
1101 |
|
* <tr><td>":"</td> <td>t</td> <td>{ "boo", "and", "foo" }</td></tr> |
1102 |
|
* <tr><td>":"</td> <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr> |
1103 |
|
* <tr><td>"o"</td> <td>5</td> <td>{ "b", "", ":and:f", "", "" }</td></tr> |
1104 |
|
* <tr><td>"o"</td> <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr> |
1105 |
|
* <tr><td>"o"</td> <td>0</td> <td>{ "b", "", ":and:f" }</td></tr> |
1106 |
|
* </table> |
1107 |
|
* |
1108 |
|
* <p>This is shorthand for |
1109 |
|
* <code>{@link Pattern}.compile(regex).split(this, limit)</code>. |
1110 |
|
* |
1111 |
|
* @param regex the pattern to match |
1112 |
|
* @param limit the limit threshold |
1113 |
|
* @return the array of split strings |
1114 |
|
* @throws NullPointerException if regex or replacement is null |
1115 |
|
* @throws PatternSyntaxExceptions if regex is invalid |
1116 |
|
* @since 1.4 |
1117 |
|
* @XXX Add this method. |
1118 |
|
public String[] split(String regex, int limit) |
1119 |
|
{ |
1120 |
|
return Pattern.compile(regex).split(this, limit); |
1121 |
|
} |
1122 |
|
*/ |
1123 |
|
|
1124 |
|
/** |
1125 |
|
* Split this string around the matches of a regular expression. Each |
1126 |
|
* element of the returned array is the largest block of characters not |
1127 |
|
* terminated by the regular expression, in the order the matches are found. |
1128 |
|
* The array length is unlimited, and trailing empty entries are discarded, |
1129 |
|
* as though calling <code>split(regex, 0)</code>. |
1130 |
|
* |
1131 |
|
* @param regex the pattern to match |
1132 |
|
* @return the array of split strings |
1133 |
|
* @throws NullPointerException if regex or replacement is null |
1134 |
|
* @throws PatternSyntaxExceptions if regex is invalid |
1135 |
|
* @see #split(String, int) |
1136 |
|
* @since 1.4 |
1137 |
|
* @XXX Add this method. |
1138 |
|
public String[] split(String regex) |
1139 |
|
{ |
1140 |
|
return Pattern.compile(regex).split(this, 0); |
1141 |
|
} |
1142 |
|
*/ |
1143 |
|
|
1144 |
|
/** |
1145 |
|
* Lowercases this String according to a particular locale. This uses |
1146 |
|
* Unicode's special case mappings, as applied to the given Locale, so the |
1147 |
|
* resulting string may be a different length. |
1148 |
* |
* |
1149 |
* @return new lowercased String, |
* @param loc locale to use |
1150 |
* or `this' if no characters where lowercased |
* @return new lowercased String, or this if no characters were lowercased |
1151 |
|
* @see #toUpperCase(Locale) |
1152 |
|
* @since 1.1 |
1153 |
*/ |
*/ |
1154 |
public String toLowerCase() { |
public String toLowerCase(Locale loc) |
1155 |
|
{ |
1156 |
|
// XXX Fix this to follow Unicode rules. |
1157 |
char[] newStr = new char[count]; |
char[] newStr = new char[count]; |
1158 |
for (int i = 0; i < count; i++) |
for (int i = 0; i < count; i++) |
1159 |
newStr[i] = Character.toLowerCase(value[i]); |
newStr[i] = Character.toLowerCase(value[i]); |
1160 |
for (int i = 0; i < count; i++) |
for (int i = 0; i < count; i++) |
1161 |
if (value[i] != newStr[i]) |
if (value[i] != newStr[i]) |
1162 |
return new String(newStr); |
return new String(newStr); |
1163 |
return this; |
return this; |
1164 |
} |
} |
1165 |
|
|
1166 |
/** |
/** |
1167 |
* Lowercases this String according to a particular locale. |
* Lowercases this String. This uses Unicode's special case mappings, as |
1168 |
* In general, this method has the same results as toLowerCase(). |
* applied to the platform's default Locale, so the resulting string may |
1169 |
* |
* be a different length. |
|
* @param loc locale to use |
|
1170 |
* |
* |
1171 |
* @return new lowercased String, or `this' if no characters were lowercased |
* @return new lowercased String, or this if no characters where lowercased |
1172 |
|
* @see #toLowerCase(Locale) |
1173 |
*/ |
*/ |
1174 |
public String toLowerCase(Locale loc) { |
public String toLowerCase() |
1175 |
return toLowerCase(); |
{ |
1176 |
|
return toLowerCase(Locale.getDefault()); |
1177 |
} |
} |
1178 |
|
|
1179 |
/** |
/** |
1180 |
* Uppercases this String. |
* Uppercases this String according to a particular locale. This uses |
1181 |
|
* Unicode's special case mappings, as applied to the given Locale, so the |
1182 |
|
* resulting string may be a different length. |
1183 |
* |
* |
1184 |
* @return new uppercased String, or `this' if no characters were uppercased |
* @param loc locale to use |
1185 |
|
* @return new uppercased String, or this if no characters were uppercased |
1186 |
|
* @see #toLowerCase(Locale) |
1187 |
|
* @since 1.1 |
1188 |
*/ |
*/ |
1189 |
public String toUpperCase() { |
public String toUpperCase(Locale loc) |
1190 |
|
{ |
1191 |
|
// XXX Fix this to follow Unicode rules. |
1192 |
char[] newStr = new char[count]; |
char[] newStr = new char[count]; |
1193 |
for (int i = 0; i < count; i++) |
for (int i = 0; i < count; i++) |
1194 |
newStr[i] = Character.toUpperCase(value[i]); |
newStr[i] = Character.toUpperCase(value[i]); |
1195 |
for (int i = 0; i < count; i++) |
for (int i = 0; i < count; i++) |
1196 |
if (value[i] != newStr[i]) |
if (value[i] != newStr[i]) |
1197 |
return new String(newStr); |
return new String(newStr); |
1198 |
return this; |
return this; |
1199 |
} |
} |
1200 |
|
|
1201 |
/** |
/** |
1202 |
* Uppercases this String according to a particular locale. |
* Uppercases this String. This uses Unicode's special case mappings, as |
1203 |
* In general, this method has the same results as toUpperCase(). |
* applied to the platform's default Locale, so the resulting string may |
1204 |
|
* be a different length. |
1205 |
* |
* |
1206 |
* @param loc locale to use |
* @return new uppercased String, or this if no characters where uppercased |
1207 |
* |
* @see #toUpperCase(Locale) |
|
* @return new uppercased String, or `this' if no characters were uppercased |
|
1208 |
*/ |
*/ |
1209 |
public String toUpperCase(Locale loc) { |
public String toUpperCase() |
1210 |
return toUpperCase(); |
{ |
1211 |
|
return toUpperCase(Locale.getDefault()); |
1212 |
} |
} |
1213 |
|
|
1214 |
/** |
/** |
1215 |
* Trims all ASCII control characters (includes whitespace) from |
* Trims all characters less than or equal to ' ' (many ASCII control |
1216 |
* the beginning and end of this String. |
* characters, and all {@link Character#whitespace(char)}) from the |
1217 |
|
* beginning and end of this String. |
1218 |
* |
* |
1219 |
* @return new trimmed String, or `this' if the String was empty |
* @return new trimmed String, or this if nothing trimmed |
|
* or contained characters greater than '\u0020' at index zero, |
|
|
* and index this.length()-1. |
|
1220 |
*/ |
*/ |
1221 |
public String trim() { |
public String trim() |
1222 |
if (count == 0 || (value[0] > '\u0020' && value[count-1] > '\u0020')) |
{ |
1223 |
|
if (count == 0 || (value[0] > '\u0020' && value[count - 1] > '\u0020')) |
1224 |
return this; |
return this; |
1225 |
int begin = 0; |
int begin = 0; |
1226 |
for (;; begin++) |
do |
1227 |
{ |
{ |
1228 |
if (begin == count) |
if (begin == count) |
1229 |
return ""; |
return ""; |
|
if (value[begin] > '\u0020') |
|
|
break; |
|
1230 |
} |
} |
1231 |
|
while (value[begin++] <= '\u0020'); |
1232 |
int end = count; |
int end = count; |
1233 |
for (;;) |
while (value[--end] <= '\u0020'); |
1234 |
if (value[--end] > '\u0020') |
|
|
break; |
|
1235 |
return substring(begin, end + 1); |
return substring(begin, end + 1); |
1236 |
} |
} |
1237 |
|
|
1238 |
/** |
/** |
1239 |
* Returns a String representation of an Object. |
* Returns this, as it is already a String! |
1240 |
* |
* |
1241 |
* @param obj the Object |
* @return this |
1242 |
|
*/ |
1243 |
|
public String toString() |
1244 |
|
{ |
1245 |
|
return this; |
1246 |
|
} |
1247 |
|
|
1248 |
|
/** |
1249 |
|
* Copies the contents of this String into a character array. Subsequent |
1250 |
|
* changes to the array do not affect the String. |
1251 |
* |
* |
1252 |
* @return "null" if `obj' is null, else `obj.toString()' |
* @return character array copying the String |
1253 |
*/ |
*/ |
1254 |
public static String valueOf(Object obj) { |
public char[] toCharArray() |
1255 |
return (obj == null) ? "null" : obj.toString(); |
{ |
1256 |
|
char[] copy = new char[count]; |
1257 |
|
System.arraycopy(value, 0, copy, 0, count); |
1258 |
|
return copy; |
1259 |
} |
} |
1260 |
|
|
1261 |
/** |
/** |
1262 |
* Returns a String representation of a character array. |
* Returns a String representation of an Object. This is "null" if the |
1263 |
|
* object is null, otherwise it is <code>obj.toString()</code> (which |
1264 |
|
* can be null). |
1265 |
* |
* |
1266 |
* @param data the character array |
* @param obj the Object |
1267 |
|
* @return the string conversion of obj |
1268 |
|
*/ |
1269 |
|
public static String valueOf(Object obj) |
1270 |
|
{ |
1271 |
|
return obj == null ? "null" : obj.toString(); |
1272 |
|
} |
1273 |
|
|
1274 |
|
/** |
1275 |
|
* Returns a String representation of a character array. Subsequent |
1276 |
|
* changes to the array do not affect the String. |
1277 |
* |
* |
1278 |
* @return a String containing the same character sequence as `data' |
* @param data the character array |
1279 |
|
* @return a String containing the same character sequence as data |
1280 |
|
* @throws NullPointerException if data is null |
1281 |
|
* @see #valueOf(char[], int, int) |
1282 |
|
* @see #String(char[]) |
1283 |
*/ |
*/ |
1284 |
public static String valueOf(char[] data) throws NullPointerException { |
public static String valueOf(char[] data) |
1285 |
return new String(data); |
{ |
1286 |
|
return new String(data, 0, data.length); |
1287 |
} |
} |
1288 |
|
|
1289 |
/** |
/** |
1290 |
* Returns a String representing the character sequence of the char |
* Returns a String representing the character sequence of the char array, |
1291 |
* array, starting at the specified offset, and copying chars up |
* starting at the specified offset, and copying chars up to the specified |
1292 |
* to the specified count. |
* count. Subsequent changes to the array do not affect the String. |
1293 |
* |
* |
1294 |
* @param data character array |
* @param data character array |
1295 |
* @param offset position (base 0) to start copying out of `data' |
* @param offset position (base 0) to start copying out of data |
1296 |
* @param count the number of characters from `data' to copy |
* @param count the number of characters from data to copy |
1297 |
* |
* @return String containing the chars from data[offset..offset+count] |
1298 |
* @return String containing the chars from `data[offset..offset+count]' |
* @throws NullPointerException if data is null |
1299 |
* |
* @throws IndexOutOfBoundsException if (offset < 0 || count < 0 |
1300 |
* @exception StringIndexOutOfBoundsException |
* || offset + count > data.length) |
1301 |
* if (offset < 0 || count < 0 || offset+count > data.length) |
* (while unspecified, this is a StringIndexOutOfBoundsException) |
1302 |
|
* @see #String(char[], int, int) |
1303 |
*/ |
*/ |
1304 |
public static String valueOf(char[] data, int offset, int count) |
public static String valueOf(char[] data, int offset, int count) |
1305 |
throws NullPointerException, IndexOutOfBoundsException { |
{ |
1306 |
|
return new String(data, offset, count); |
1307 |
|
} |
1308 |
|
|
1309 |
|
/** |
1310 |
|
* Returns a String representing the character sequence of the char array, |
1311 |
|
* starting at the specified offset, and copying chars up to the specified |
1312 |
|
* count. Subsequent changes to the array do not affect the String. |
1313 |
|
* |
1314 |
|
* @param data character array |
1315 |
|
* @param offset position (base 0) to start copying out of data |
1316 |
|
* @param count the number of characters from data to copy |
1317 |
|
* @return String containing the chars from data[offset..offset+count] |
1318 |
|
* @throws NullPointerException if data is null |
1319 |
|
* @throws IndexOutOfBoundsException if (offset < 0 || count < 0 |
1320 |
|
* || offset + count > data.length) |
1321 |
|
* (while unspecified, this is a StringIndexOutOfBoundsException) |
1322 |
|
* @see #String(char[], int, int) |
1323 |
|
*/ |
1324 |
|
public static String copyValueOf(char[] data, int offset, int count) |
1325 |
|
{ |
1326 |
return new String(data, offset, count); |
return new String(data, offset, count); |
1327 |
} |
} |
1328 |
|
|
1329 |
/** |
/** |
1330 |
|
* Returns a String representation of a character array. Subsequent |
1331 |
|
* changes to the array do not affect the String. |
1332 |
|
* |
1333 |
|
* @param data the character array |
1334 |
|
* @return a String containing the same character sequence as data |
1335 |
|
* @throws NullPointerException if data is null |
1336 |
|
* @see #copyValueOf(char[], int, int) |
1337 |
|
* @see #String(char[]) |
1338 |
|
*/ |
1339 |
|
public static String copyValueOf(char[] data) |
1340 |
|
{ |
1341 |
|
return new String(data, 0, data.length); |
1342 |
|
} |
1343 |
|
|
1344 |
|
/** |
1345 |
* Returns a String representing a boolean. |
* Returns a String representing a boolean. |
1346 |
* |
* |
1347 |
* @param b the boolean |
* @param b the boolean |
1348 |
* |
* @return "true" if b is true, else "false" |
|
* @return "true" if `b' is true, else "false" |
|
1349 |
*/ |
*/ |
1350 |
public static String valueOf(boolean b) { |
public static String valueOf(boolean b) |
1351 |
return (b) ? "true" : "false"; |
{ |
1352 |
|
return b ? "true" : "false"; |
1353 |
} |
} |
1354 |
|
|
1355 |
/** |
/** |
1356 |
* Returns a String representing a character. |
* Returns a String representing a character. |
|
* |
|
|
* @param c the character |
|
1357 |
* |
* |
1358 |
* @return String containing the single character `c'. |
* @param c the character |
1359 |
|
* @return String containing the single character c |
1360 |
*/ |
*/ |
1361 |
public static String valueOf(char c) { |
public static String valueOf(char c) |
1362 |
|
{ |
1363 |
|
// XXX Share this array. |
1364 |
return new String(new char[] { c }); |
return new String(new char[] { c }); |
1365 |
} |
} |
1366 |
|
|
1368 |
* Returns a String representing an integer. |
* Returns a String representing an integer. |
1369 |
* |
* |
1370 |
* @param i the integer |
* @param i the integer |
1371 |
* |
* @return String containing the integer in base 10 |
1372 |
* @return Integer.toString(i) |
* @see Integer#toString(int) |
1373 |
*/ |
*/ |
1374 |
public static String valueOf(int i) { |
public static String valueOf(int i) |
1375 |
|
{ |
1376 |
// See Integer to understand why we call the two-arg variant. |
// See Integer to understand why we call the two-arg variant. |
1377 |
return Integer.toString(i, 10); |
return Integer.toString(i, 10); |
1378 |
} |
} |
1381 |
* Returns a String representing a long. |
* Returns a String representing a long. |
1382 |
* |
* |
1383 |
* @param i the long |
* @param i the long |
1384 |
* |
* @return String containing the long in base 10 |
1385 |
* @return Long.toString(i) |
* @see Long#toString(long) |
1386 |
*/ |
*/ |
1387 |
public static String valueOf(long l) { |
public static String valueOf(long l) |
1388 |
|
{ |
1389 |
return Long.toString(l); |
return Long.toString(l); |
1390 |
} |
} |
1391 |
|
|
1393 |
* Returns a String representing a float. |
* Returns a String representing a float. |
1394 |
* |
* |
1395 |
* @param i the float |
* @param i the float |
1396 |
* |
* @return String containing the float |
1397 |
* @return Float.toString(i) |
* @see Float#toString(float) |
1398 |
*/ |
*/ |
1399 |
public static String valueOf(float f) { |
public static String valueOf(float f) |
1400 |
|
{ |
1401 |
return Float.toString(f); |
return Float.toString(f); |
1402 |
} |
} |
1403 |
|
|
1405 |
* Returns a String representing a double. |
* Returns a String representing a double. |
1406 |
* |
* |
1407 |
* @param i the double |
* @param i the double |
1408 |
* |
* @return String containing the double |
1409 |
* @return Double.toString(i) |
* @see Double#toString(double) |
1410 |
*/ |
*/ |
1411 |
public static String valueOf(double d) { |
public static String valueOf(double d) |
1412 |
|
{ |
1413 |
return Double.toString(d); |
return Double.toString(d); |
1414 |
} |
} |
1415 |
|
|
1416 |
/** |
/** |
1417 |
* Fetches this String from the intern hashtable. |
* Fetches this String from the intern hashtable. If two Strings are |
1418 |
* If two Strings are considered equal, by the equals() method, |
* considered equal, by the equals() method, then intern() will return the |
1419 |
* then intern() will return the same String instance. |
* same String instance. ie. if (s1.equals(s2)) then |
1420 |
* ie. if (s1.equals(s2)) then (s1.intern() == s2.intern()) |
* (s1.intern() == s2.intern()). All string literals and string-valued |
1421 |
|
* constant expressions are already interned. |
1422 |
* |
* |
1423 |
* @return intern'd String |
* @return intern'd String |
1424 |
*/ |
*/ |
1425 |
public String intern() { |
public String intern() |
1426 |
|
{ |
1427 |
|
// XXX Synchronize access to the table, to avoid races. |
1428 |
Object o = internTable.get(this); |
Object o = internTable.get(this); |
1429 |
if (o != null) return (String) o; |
if (o != null) |
1430 |
|
return (String) o; |
1431 |
internTable.put(this, this); |
internTable.put(this, this); |
1432 |
return this; |
return this; |
1433 |
} |
} |
|
|
|
|
/** |
|
|
* Creates a string from the character array. The array is first copied. |
|
|
* |
|
|
* @param data the array of characters |
|
|
* |
|
|
* @return a String object that contains the characters of the character array |
|
|
*/ |
|
|
|
|
|
public static String copyValueOf(char[] data) { |
|
|
char[] duplicate = (char[]) data.clone(); |
|
|
return new String(duplicate); |
|
|
} |
|
|
|
|
|
/** |
|
|
* Creates a string from the specifed character subarray. The array is first copied. |
|
|
* |
|
|
* @param data the array of characters |
|
|
* @param offset the array index indicating the start of the subarray |
|
|
* @param count the number of characters to use for the subarray |
|
|
* |
|
|
* @return a String object that contains the characters of the character subarray |
|
|
*/ |
|
|
|
|
|
public static String copyValueOf(char[] data, int offset, int count) { |
|
|
char[] duplicate = new char[count]; |
|
|
System.arraycopy(duplicate, 0, data, offset, count); |
|
|
return new String(duplicate); |
|
|
} |
|
1434 |
} |
} |