• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.lang;
19 
20 import java.io.Serializable;
21 import java.io.UnsupportedEncodingException;
22 import java.nio.ByteBuffer;
23 import java.nio.CharBuffer;
24 import java.nio.charset.Charset;
25 import java.nio.charset.Charsets;
26 import java.util.Arrays;
27 import java.util.Comparator;
28 import java.util.Formatter;
29 import java.util.Locale;
30 import java.util.regex.Pattern;
31 import libcore.util.EmptyArray;
32 
33 /**
34  * An immutable sequence of characters/code units ({@code char}s). A
35  * {@code String} is represented by array of UTF-16 values, such that
36  * Unicode supplementary characters (code points) are stored/encoded as
37  * surrogate pairs via Unicode code units ({@code char}).
38  *
39  * <a name="backing_array"><h3>Backing Arrays</h3></a>
40  * This class is implemented using a char[]. The length of the array may exceed
41  * the length of the string. For example, the string "Hello" may be backed by
42  * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with
43  * offset 0 and length 5.
44  *
45  * <p>Multiple strings can share the same char[] because strings are immutable.
46  * The {@link #substring} method <strong>always</strong> returns a string that
47  * shares the backing array of its source string. Generally this is an
48  * optimization: fewer character arrays need to be allocated, and less copying
49  * is necessary. But this can also lead to unwanted heap retention. Taking a
50  * short substring of long string means that the long shared char[] won't be
51  * garbage until both strings are garbage. This typically happens when parsing
52  * small substrings out of a large input. To avoid this where necessary, call
53  * {@code new String(longString.subString(...))}. The string copy constructor
54  * always ensures that the backing array is no larger than necessary.
55  *
56  * @see StringBuffer
57  * @see StringBuilder
58  * @see Charset
59  * @since 1.0
60  */
61 public final class String implements Serializable, Comparable<String>, CharSequence {
62 
63     private static final long serialVersionUID = -6849794470754667710L;
64 
65     private static final char REPLACEMENT_CHAR = (char) 0xfffd;
66 
67     /**
68      * CaseInsensitiveComparator compares Strings ignoring the case of the
69      * characters.
70      */
71     private static final class CaseInsensitiveComparator implements
72             Comparator<String>, Serializable {
73         private static final long serialVersionUID = 8575799808933029326L;
74 
75         /**
76          * Compare the two objects to determine the relative ordering.
77          *
78          * @param o1
79          *            an Object to compare
80          * @param o2
81          *            an Object to compare
82          * @return an int < 0 if object1 is less than object2, 0 if they are
83          *         equal, and > 0 if object1 is greater
84          *
85          * @exception ClassCastException
86          *                if objects are not the correct type
87          */
compare(String o1, String o2)88         public int compare(String o1, String o2) {
89             return o1.compareToIgnoreCase(o2);
90         }
91     }
92 
93     /**
94      * A comparator ignoring the case of the characters.
95      */
96     public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
97 
98     private static final char[] ASCII;
99     static {
100         ASCII = new char[128];
101         for (int i = 0; i < ASCII.length; ++i) {
102             ASCII[i] = (char) i;
103         }
104     }
105 
106     private final char[] value;
107 
108     private final int offset;
109 
110     private final int count;
111 
112     private int hashCode;
113 
114     /**
115      * Creates an empty string.
116      */
String()117     public String() {
118         value = EmptyArray.CHAR;
119         offset = 0;
120         count = 0;
121     }
122 
123     /*
124      * Private constructor used for JIT optimization.
125      */
126     @SuppressWarnings("unused")
String(String s, char c)127     private String(String s, char c) {
128         offset = 0;
129         value = new char[s.count + 1];
130         count = s.count + 1;
131         System.arraycopy(s.value, s.offset, value, 0, s.count);
132         value[s.count] = c;
133     }
134 
135     /**
136      * Converts the byte array to a string using the system's
137      * {@link java.nio.charset.Charset#defaultCharset default charset}.
138      */
139     @FindBugsSuppressWarnings("DM_DEFAULT_ENCODING")
String(byte[] data)140     public String(byte[] data) {
141         this(data, 0, data.length);
142     }
143 
144     /**
145      * Converts the byte array to a string, setting the high byte of every
146      * character to the specified value.
147      *
148      * @param data
149      *            the byte array to convert to a string.
150      * @param high
151      *            the high byte to use.
152      * @throws NullPointerException
153      *             if {@code data == null}.
154      * @deprecated Use {@link #String(byte[])} or {@link #String(byte[], String)} instead.
155      */
156     @Deprecated
String(byte[] data, int high)157     public String(byte[] data, int high) {
158         this(data, high, 0, data.length);
159     }
160 
161     /**
162      * Converts a subsequence of the byte array to a string using the system's
163      * {@link java.nio.charset.Charset#defaultCharset default charset}.
164      *
165      * @throws NullPointerException
166      *             if {@code data == null}.
167      * @throws IndexOutOfBoundsException
168      *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
169      */
String(byte[] data, int offset, int byteCount)170     public String(byte[] data, int offset, int byteCount) {
171         this(data, offset, byteCount, Charset.defaultCharset());
172     }
173 
174     /**
175      * Converts the byte array to a string, setting the high byte of every
176      * character to {@code high}.
177      *
178      * @throws NullPointerException
179      *             if {@code data == null}.
180      * @throws IndexOutOfBoundsException
181      *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
182      *
183      * @deprecated Use {@link #String(byte[], int, int)} instead.
184      */
185     @Deprecated
String(byte[] data, int high, int offset, int byteCount)186     public String(byte[] data, int high, int offset, int byteCount) {
187         if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
188             throw failedBoundsCheck(data.length, offset, byteCount);
189         }
190         this.offset = 0;
191         this.value = new char[byteCount];
192         this.count = byteCount;
193         high <<= 8;
194         for (int i = 0; i < count; i++) {
195             value[i] = (char) (high + (data[offset++] & 0xff));
196         }
197     }
198 
199     /**
200      * Converts the byte array to a string using the named charset.
201      *
202      * <p>The behavior when the bytes cannot be decoded by the named charset
203      * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
204      *
205      * @throws NullPointerException
206      *             if {@code data == null}.
207      * @throws IndexOutOfBoundsException
208      *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
209      * @throws UnsupportedEncodingException
210      *             if the named charset is not supported.
211      */
String(byte[] data, int offset, int byteCount, String charsetName)212     public String(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException {
213         this(data, offset, byteCount, Charset.forNameUEE(charsetName));
214     }
215 
216     /**
217      * Converts the byte array to a string using the named charset.
218      *
219      * <p>The behavior when the bytes cannot be decoded by the named charset
220      * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
221      *
222      * @throws NullPointerException
223      *             if {@code data == null}.
224      * @throws UnsupportedEncodingException
225      *             if {@code charsetName} is not supported.
226      */
String(byte[] data, String charsetName)227     public String(byte[] data, String charsetName) throws UnsupportedEncodingException {
228         this(data, 0, data.length, Charset.forNameUEE(charsetName));
229     }
230 
231     /**
232      * Converts the byte array to a string using the given charset.
233      *
234      * <p>The behavior when the bytes cannot be decoded by the given charset
235      * is to replace malformed input and unmappable characters with the charset's default
236      * replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control.
237      *
238      * @throws IndexOutOfBoundsException
239      *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
240      * @throws NullPointerException
241      *             if {@code data == null}
242      *
243      * @since 1.6
244      */
String(byte[] data, int offset, int byteCount, Charset charset)245     public String(byte[] data, int offset, int byteCount, Charset charset) {
246         if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
247             throw failedBoundsCheck(data.length, offset, byteCount);
248         }
249 
250         // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed and because 'count' and
251         // 'value' are final.
252         String canonicalCharsetName = charset.name();
253         if (canonicalCharsetName.equals("UTF-8")) {
254             byte[] d = data;
255             char[] v = new char[byteCount];
256 
257             int idx = offset;
258             int last = offset + byteCount;
259             int s = 0;
260 outer:
261             while (idx < last) {
262                 byte b0 = d[idx++];
263                 if ((b0 & 0x80) == 0) {
264                     // 0xxxxxxx
265                     // Range:  U-00000000 - U-0000007F
266                     int val = b0 & 0xff;
267                     v[s++] = (char) val;
268                 } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) ||
269                         ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) {
270                     int utfCount = 1;
271                     if ((b0 & 0xf0) == 0xe0) utfCount = 2;
272                     else if ((b0 & 0xf8) == 0xf0) utfCount = 3;
273                     else if ((b0 & 0xfc) == 0xf8) utfCount = 4;
274                     else if ((b0 & 0xfe) == 0xfc) utfCount = 5;
275 
276                     // 110xxxxx (10xxxxxx)+
277                     // Range:  U-00000080 - U-000007FF (count == 1)
278                     // Range:  U-00000800 - U-0000FFFF (count == 2)
279                     // Range:  U-00010000 - U-001FFFFF (count == 3)
280                     // Range:  U-00200000 - U-03FFFFFF (count == 4)
281                     // Range:  U-04000000 - U-7FFFFFFF (count == 5)
282 
283                     if (idx + utfCount > last) {
284                         v[s++] = REPLACEMENT_CHAR;
285                         break;
286                     }
287 
288                     // Extract usable bits from b0
289                     int val = b0 & (0x1f >> (utfCount - 1));
290                     for (int i = 0; i < utfCount; i++) {
291                         byte b = d[idx++];
292                         if ((b & 0xC0) != 0x80) {
293                             v[s++] = REPLACEMENT_CHAR;
294                             idx--; // Put the input char back
295                             continue outer;
296                         }
297                         // Push new bits in from the right side
298                         val <<= 6;
299                         val |= b & 0x3f;
300                     }
301 
302                     // Note: Java allows overlong char
303                     // specifications To disallow, check that val
304                     // is greater than or equal to the minimum
305                     // value for each count:
306                     //
307                     // count    min value
308                     // -----   ----------
309                     //   1           0x80
310                     //   2          0x800
311                     //   3        0x10000
312                     //   4       0x200000
313                     //   5      0x4000000
314 
315                     // Allow surrogate values (0xD800 - 0xDFFF) to
316                     // be specified using 3-byte UTF values only
317                     if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) {
318                         v[s++] = REPLACEMENT_CHAR;
319                         continue;
320                     }
321 
322                     // Reject chars greater than the Unicode maximum of U+10FFFF.
323                     if (val > 0x10FFFF) {
324                         v[s++] = REPLACEMENT_CHAR;
325                         continue;
326                     }
327 
328                     // Encode chars from U+10000 up as surrogate pairs
329                     if (val < 0x10000) {
330                         v[s++] = (char) val;
331                     } else {
332                         int x = val & 0xffff;
333                         int u = (val >> 16) & 0x1f;
334                         int w = (u - 1) & 0xffff;
335                         int hi = 0xd800 | (w << 6) | (x >> 10);
336                         int lo = 0xdc00 | (x & 0x3ff);
337                         v[s++] = (char) hi;
338                         v[s++] = (char) lo;
339                     }
340                 } else {
341                     // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff
342                     v[s++] = REPLACEMENT_CHAR;
343                 }
344             }
345 
346             if (s == byteCount) {
347                 // We guessed right, so we can use our temporary array as-is.
348                 this.offset = 0;
349                 this.value = v;
350                 this.count = s;
351             } else {
352                 // Our temporary array was too big, so reallocate and copy.
353                 this.offset = 0;
354                 this.value = new char[s];
355                 this.count = s;
356                 System.arraycopy(v, 0, value, 0, s);
357             }
358         } else if (canonicalCharsetName.equals("ISO-8859-1")) {
359             this.offset = 0;
360             this.value = new char[byteCount];
361             this.count = byteCount;
362             Charsets.isoLatin1BytesToChars(data, offset, byteCount, value);
363         } else if (canonicalCharsetName.equals("US-ASCII")) {
364             this.offset = 0;
365             this.value = new char[byteCount];
366             this.count = byteCount;
367             Charsets.asciiBytesToChars(data, offset, byteCount, value);
368         } else {
369             CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
370             this.offset = 0;
371             this.count = cb.length();
372             if (count > 0) {
373                 // We could use cb.array() directly, but that would mean we'd have to trust
374                 // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later,
375                 // which would break String's immutability guarantee. It would also tend to
376                 // mean that we'd be wasting memory because CharsetDecoder doesn't trim the
377                 // array. So we copy.
378                 this.value = new char[count];
379                 System.arraycopy(cb.array(), 0, value, 0, count);
380             } else {
381                 this.value = EmptyArray.CHAR;
382             }
383         }
384     }
385 
386     /**
387      * Converts the byte array to a String using the given charset.
388      *
389      * @throws NullPointerException if {@code data == null}
390      * @since 1.6
391      */
String(byte[] data, Charset charset)392     public String(byte[] data, Charset charset) {
393         this(data, 0, data.length, charset);
394     }
395 
396     /**
397      * Initializes this string to contain the characters in the specified
398      * character array. Modifying the character array after creating the string
399      * has no effect on the string.
400      *
401      * @throws NullPointerException if {@code data == null}
402      */
String(char[] data)403     public String(char[] data) {
404         this(data, 0, data.length);
405     }
406 
407     /**
408      * Initializes this string to contain the specified characters in the
409      * character array. Modifying the character array after creating the string
410      * has no effect on the string.
411      *
412      * @throws NullPointerException
413      *             if {@code data == null}.
414      * @throws IndexOutOfBoundsException
415      *             if {@code charCount < 0 || offset < 0 || offset + charCount > data.length}
416      */
String(char[] data, int offset, int charCount)417     public String(char[] data, int offset, int charCount) {
418         if ((offset | charCount) < 0 || charCount > data.length - offset) {
419             throw failedBoundsCheck(data.length, offset, charCount);
420         }
421         this.offset = 0;
422         this.value = new char[charCount];
423         this.count = charCount;
424         System.arraycopy(data, offset, value, 0, count);
425     }
426 
427     /*
428      * Internal version of the String(char[], int, int) constructor.
429      * Does not range check, null check, or copy the character array.
430      */
String(int offset, int charCount, char[] chars)431     String(int offset, int charCount, char[] chars) {
432         this.value = chars;
433         this.offset = offset;
434         this.count = charCount;
435     }
436 
437     /**
438      * Constructs a new string with the same sequence of characters as {@code
439      * toCopy}. The returned string's <a href="#backing_array">backing array</a>
440      * is no larger than necessary.
441      */
String(String toCopy)442     public String(String toCopy) {
443         value = (toCopy.value.length == toCopy.count)
444                 ? toCopy.value
445                 : Arrays.copyOfRange(toCopy.value, toCopy.offset, toCopy.offset + toCopy.length());
446         offset = 0;
447         count = value.length;
448     }
449 
450     /*
451      * Private constructor useful for JIT optimization.
452      */
453     @SuppressWarnings( { "unused", "nls" })
String(String s1, String s2)454     private String(String s1, String s2) {
455         if (s1 == null) {
456             s1 = "null";
457         }
458         if (s2 == null) {
459             s2 = "null";
460         }
461         count = s1.count + s2.count;
462         value = new char[count];
463         offset = 0;
464         System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
465         System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
466     }
467 
468     /*
469      * Private constructor useful for JIT optimization.
470      */
471     @SuppressWarnings( { "unused", "nls" })
String(String s1, String s2, String s3)472     private String(String s1, String s2, String s3) {
473         if (s1 == null) {
474             s1 = "null";
475         }
476         if (s2 == null) {
477             s2 = "null";
478         }
479         if (s3 == null) {
480             s3 = "null";
481         }
482         count = s1.count + s2.count + s3.count;
483         value = new char[count];
484         offset = 0;
485         System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
486         System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
487         System.arraycopy(s3.value, s3.offset, value, s1.count + s2.count, s3.count);
488     }
489 
490     /**
491      * Creates a {@code String} from the contents of the specified
492      * {@code StringBuffer}.
493      */
String(StringBuffer stringBuffer)494     public String(StringBuffer stringBuffer) {
495         offset = 0;
496         synchronized (stringBuffer) {
497             value = stringBuffer.shareValue();
498             count = stringBuffer.length();
499         }
500     }
501 
502     /**
503      * Creates a {@code String} from the sub-array of Unicode code points.
504      *
505      * @throws NullPointerException
506      *             if {@code codePoints == null}.
507      * @throws IllegalArgumentException
508      *             if any of the elements of {@code codePoints} are not valid
509      *             Unicode code points.
510      * @throws IndexOutOfBoundsException
511      *             if {@code offset} or {@code count} are not within the bounds
512      *             of {@code codePoints}.
513      * @since 1.5
514      */
String(int[] codePoints, int offset, int count)515     public String(int[] codePoints, int offset, int count) {
516         if (codePoints == null) {
517             throw new NullPointerException("codePoints == null");
518         }
519         if ((offset | count) < 0 || count > codePoints.length - offset) {
520             throw failedBoundsCheck(codePoints.length, offset, count);
521         }
522         this.offset = 0;
523         this.value = new char[count * 2];
524         int end = offset + count;
525         int c = 0;
526         for (int i = offset; i < end; i++) {
527             c += Character.toChars(codePoints[i], this.value, c);
528         }
529         this.count = c;
530     }
531 
532     /**
533      * Creates a {@code String} from the contents of the specified {@code
534      * StringBuilder}.
535      *
536      * @throws NullPointerException
537      *             if {@code stringBuilder == null}.
538      * @since 1.5
539      */
String(StringBuilder stringBuilder)540     public String(StringBuilder stringBuilder) {
541         if (stringBuilder == null) {
542             throw new NullPointerException("stringBuilder == null");
543         }
544         this.offset = 0;
545         this.count = stringBuilder.length();
546         this.value = new char[this.count];
547         stringBuilder.getChars(0, this.count, this.value, 0);
548     }
549 
550     /*
551      * Creates a {@code String} that is s1 + v1. May be used by JIT code.
552      */
553     @SuppressWarnings("unused")
String(String s1, int v1)554     private String(String s1, int v1) {
555         if (s1 == null) {
556             s1 = "null";
557         }
558         String s2 = String.valueOf(v1);
559         int len = s1.count + s2.count;
560         value = new char[len];
561         offset = 0;
562         System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
563         System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
564         count = len;
565     }
566 
567     /**
568      * Returns the character at the specified offset in this string.
569      *
570      * @param index
571      *            the zero-based index in this string.
572      * @return the character at the index.
573      * @throws IndexOutOfBoundsException
574      *             if {@code index < 0} or {@code index >= length()}.
575      */
charAt(int index)576     public native char charAt(int index);
577 
indexAndLength(int index)578     private StringIndexOutOfBoundsException indexAndLength(int index) {
579         throw new StringIndexOutOfBoundsException(this, index);
580     }
581 
startEndAndLength(int start, int end)582     private StringIndexOutOfBoundsException startEndAndLength(int start, int end) {
583         throw new StringIndexOutOfBoundsException(this, start, end - start);
584     }
585 
failedBoundsCheck(int arrayLength, int offset, int count)586     private StringIndexOutOfBoundsException failedBoundsCheck(int arrayLength, int offset, int count) {
587         throw new StringIndexOutOfBoundsException(arrayLength, offset, count);
588     }
589 
590     /**
591      * This isn't equivalent to either of ICU's u_foldCase case folds, and thus any of the Unicode
592      * case folds, but it's what the RI uses.
593      */
foldCase(char ch)594     private char foldCase(char ch) {
595         if (ch < 128) {
596             if ('A' <= ch && ch <= 'Z') {
597                 return (char) (ch + ('a' - 'A'));
598             }
599             return ch;
600         }
601         return Character.toLowerCase(Character.toUpperCase(ch));
602     }
603 
604     /**
605      * Compares the specified string to this string using the Unicode values of
606      * the characters. Returns 0 if the strings contain the same characters in
607      * the same order. Returns a negative integer if the first non-equal
608      * character in this string has a Unicode value which is less than the
609      * Unicode value of the character at the same position in the specified
610      * string, or if this string is a prefix of the specified string. Returns a
611      * positive integer if the first non-equal character in this string has a
612      * Unicode value which is greater than the Unicode value of the character at
613      * the same position in the specified string, or if the specified string is
614      * a prefix of this string.
615      *
616      * @param string
617      *            the string to compare.
618      * @return 0 if the strings are equal, a negative integer if this string is
619      *         before the specified string, or a positive integer if this string
620      *         is after the specified string.
621      * @throws NullPointerException
622      *             if {@code string} is {@code null}.
623      */
compareTo(String string)624     public native int compareTo(String string);
625 
626     /**
627      * Compares the specified string to this string using the Unicode values of
628      * the characters, ignoring case differences. Returns 0 if the strings
629      * contain the same characters in the same order. Returns a negative integer
630      * if the first non-equal character in this string has a Unicode value which
631      * is less than the Unicode value of the character at the same position in
632      * the specified string, or if this string is a prefix of the specified
633      * string. Returns a positive integer if the first non-equal character in
634      * this string has a Unicode value which is greater than the Unicode value
635      * of the character at the same position in the specified string, or if the
636      * specified string is a prefix of this string.
637      *
638      * @param string
639      *            the string to compare.
640      * @return 0 if the strings are equal, a negative integer if this string is
641      *         before the specified string, or a positive integer if this string
642      *         is after the specified string.
643      * @throws NullPointerException
644      *             if {@code string} is {@code null}.
645      */
compareToIgnoreCase(String string)646     public int compareToIgnoreCase(String string) {
647         int o1 = offset, o2 = string.offset, result;
648         int end = offset + (count < string.count ? count : string.count);
649         char c1, c2;
650         char[] target = string.value;
651         while (o1 < end) {
652             if ((c1 = value[o1++]) == (c2 = target[o2++])) {
653                 continue;
654             }
655             c1 = foldCase(c1);
656             c2 = foldCase(c2);
657             if ((result = c1 - c2) != 0) {
658                 return result;
659             }
660         }
661         return count - string.count;
662     }
663 
664     /**
665      * Concatenates this string and the specified string.
666      *
667      * @param string
668      *            the string to concatenate
669      * @return a new string which is the concatenation of this string and the
670      *         specified string.
671      */
concat(String string)672     public String concat(String string) {
673         if (string.count > 0 && count > 0) {
674             char[] buffer = new char[count + string.count];
675             System.arraycopy(value, offset, buffer, 0, count);
676             System.arraycopy(string.value, string.offset, buffer, count, string.count);
677             return new String(0, buffer.length, buffer);
678         }
679         return count == 0 ? string : this;
680     }
681 
682     /**
683      * Creates a new string containing the characters in the specified character
684      * array. Modifying the character array after creating the string has no
685      * effect on the string.
686      *
687      * @param data
688      *            the array of characters.
689      * @return the new string.
690      * @throws NullPointerException
691      *             if {@code data} is {@code null}.
692      */
copyValueOf(char[] data)693     public static String copyValueOf(char[] data) {
694         return new String(data, 0, data.length);
695     }
696 
697     /**
698      * Creates a new string containing the specified characters in the character
699      * array. Modifying the character array after creating the string has no
700      * effect on the string.
701      *
702      * @param data
703      *            the array of characters.
704      * @param start
705      *            the starting offset in the character array.
706      * @param length
707      *            the number of characters to use.
708      * @return the new string.
709      * @throws NullPointerException
710      *             if {@code data} is {@code null}.
711      * @throws IndexOutOfBoundsException
712      *             if {@code length < 0, start < 0} or {@code start + length >
713      *             data.length}.
714      */
copyValueOf(char[] data, int start, int length)715     public static String copyValueOf(char[] data, int start, int length) {
716         return new String(data, start, length);
717     }
718 
719     /**
720      * Compares the specified string to this string to determine if the
721      * specified string is a suffix.
722      *
723      * @param suffix
724      *            the suffix to look for.
725      * @return {@code true} if the specified string is a suffix of this string,
726      *         {@code false} otherwise.
727      * @throws NullPointerException
728      *             if {@code suffix} is {@code null}.
729      */
endsWith(String suffix)730     public boolean endsWith(String suffix) {
731         return regionMatches(count - suffix.count, suffix, 0, suffix.count);
732     }
733 
734     /**
735      * Compares the specified object to this string and returns true if they are
736      * equal. The object must be an instance of string with the same characters
737      * in the same order.
738      *
739      * @param object
740      *            the object to compare.
741      * @return {@code true} if the specified object is equal to this string,
742      *         {@code false} otherwise.
743      * @see #hashCode
744      */
equals(Object object)745     @Override public native boolean equals(Object object);
746 
747     /**
748      * Compares the specified string to this string ignoring the case of the
749      * characters and returns true if they are equal.
750      *
751      * @param string
752      *            the string to compare.
753      * @return {@code true} if the specified string is equal to this string,
754      *         {@code false} otherwise.
755      */
756     @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
equalsIgnoreCase(String string)757     public boolean equalsIgnoreCase(String string) {
758         if (string == this) {
759             return true;
760         }
761         if (string == null || count != string.count) {
762             return false;
763         }
764         int o1 = offset, o2 = string.offset;
765         int end = offset + count;
766         char[] target = string.value;
767         while (o1 < end) {
768             char c1 = value[o1++];
769             char c2 = target[o2++];
770             if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
771                 return false;
772             }
773         }
774         return true;
775     }
776 
777     /**
778      * Mangles this string into a byte array by stripping the high order bits from
779      * each character. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
780      *
781      * @param start
782      *            the starting offset of characters to copy.
783      * @param end
784      *            the ending offset of characters to copy.
785      * @param data
786      *            the destination byte array.
787      * @param index
788      *            the starting offset in the destination byte array.
789      * @throws NullPointerException
790      *             if {@code data} is {@code null}.
791      * @throws IndexOutOfBoundsException
792      *             if {@code start < 0}, {@code end > length()}, {@code index <
793      *             0} or {@code end - start > data.length - index}.
794      * @deprecated Use {@link #getBytes()} or {@link #getBytes(String)}
795      */
796     @Deprecated
getBytes(int start, int end, byte[] data, int index)797     public void getBytes(int start, int end, byte[] data, int index) {
798         // Note: last character not copied!
799         if (start >= 0 && start <= end && end <= count) {
800             end += offset;
801             try {
802                 for (int i = offset + start; i < end; i++) {
803                     data[index++] = (byte) value[i];
804                 }
805             } catch (ArrayIndexOutOfBoundsException ignored) {
806                 throw failedBoundsCheck(data.length, index, end - start);
807             }
808         } else {
809             throw startEndAndLength(start, end);
810         }
811     }
812 
813     /**
814      * Returns a new byte array containing the characters of this string encoded using the
815      * system's {@link java.nio.charset.Charset#defaultCharset default charset}.
816      *
817      * <p>The behavior when this string cannot be represented in the system's default charset
818      * is unspecified. In practice, when the default charset is UTF-8 (as it is on Android),
819      * all strings can be encoded.
820      */
getBytes()821     public byte[] getBytes() {
822         return getBytes(Charset.defaultCharset());
823     }
824 
825     /**
826      * Returns a new byte array containing the characters of this string encoded using the
827      * named charset.
828      *
829      * <p>The behavior when this string cannot be represented in the named charset
830      * is unspecified. Use {@link java.nio.charset.CharsetEncoder} for more control.
831      *
832      * @throws UnsupportedEncodingException if the charset is not supported
833      */
getBytes(String charsetName)834     public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
835         return getBytes(Charset.forNameUEE(charsetName));
836     }
837 
838     /**
839      * Returns a new byte array containing the characters of this string encoded using the
840      * given charset.
841      *
842      * <p>The behavior when this string cannot be represented in the given charset
843      * is to replace malformed input and unmappable characters with the charset's default
844      * replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control.
845      *
846      * @since 1.6
847      */
getBytes(Charset charset)848     public byte[] getBytes(Charset charset) {
849         String canonicalCharsetName = charset.name();
850         if (canonicalCharsetName.equals("UTF-8")) {
851             return Charsets.toUtf8Bytes(value, offset, count);
852         } else if (canonicalCharsetName.equals("ISO-8859-1")) {
853             return Charsets.toIsoLatin1Bytes(value, offset, count);
854         } else if (canonicalCharsetName.equals("US-ASCII")) {
855             return Charsets.toAsciiBytes(value, offset, count);
856         } else if (canonicalCharsetName.equals("UTF-16BE")) {
857             return Charsets.toBigEndianUtf16Bytes(value, offset, count);
858         } else {
859             CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count);
860             ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer());
861             byte[] bytes = new byte[buffer.limit()];
862             buffer.get(bytes);
863             return bytes;
864         }
865     }
866 
867     /**
868      * Copies the specified characters in this string to the character array
869      * starting at the specified offset in the character array.
870      *
871      * @param start
872      *            the starting offset of characters to copy.
873      * @param end
874      *            the ending offset of characters to copy.
875      * @param buffer
876      *            the destination character array.
877      * @param index
878      *            the starting offset in the character array.
879      * @throws NullPointerException
880      *             if {@code buffer} is {@code null}.
881      * @throws IndexOutOfBoundsException
882      *             if {@code start < 0}, {@code end > length()}, {@code start >
883      *             end}, {@code index < 0}, {@code end - start > buffer.length -
884      *             index}
885      */
getChars(int start, int end, char[] buffer, int index)886     public void getChars(int start, int end, char[] buffer, int index) {
887         // Note: last character not copied!
888         if (start >= 0 && start <= end && end <= count) {
889             System.arraycopy(value, start + offset, buffer, index, end - start);
890         } else {
891             // We throw StringIndexOutOfBoundsException rather than System.arraycopy's AIOOBE.
892             throw startEndAndLength(start, end);
893         }
894     }
895 
896     /**
897      * Version of getChars without bounds checks, for use by other classes
898      * within the java.lang package only.  The caller is responsible for
899      * ensuring that start >= 0 && start <= end && end <= count.
900      */
_getChars(int start, int end, char[] buffer, int index)901     void _getChars(int start, int end, char[] buffer, int index) {
902         // NOTE last character not copied!
903         System.arraycopy(value, start + offset, buffer, index, end - start);
904     }
905 
hashCode()906     @Override public int hashCode() {
907         int hash = hashCode;
908         if (hash == 0) {
909             if (count == 0) {
910                 return 0;
911             }
912             final int end = count + offset;
913             final char[] chars = value;
914             for (int i = offset; i < end; ++i) {
915                 hash = 31*hash + chars[i];
916             }
917             hashCode = hash;
918         }
919         return hash;
920     }
921 
922     /**
923      * Searches in this string for the first index of the specified character.
924      * The search for the character starts at the beginning and moves towards
925      * the end of this string.
926      *
927      * @param c
928      *            the character to find.
929      * @return the index in this string of the specified character, -1 if the
930      *         character isn't found.
931      */
indexOf(int c)932     public int indexOf(int c) {
933         // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep.
934         if (c > 0xffff) {
935             return indexOfSupplementary(c, 0);
936         }
937         return fastIndexOf(c, 0);
938     }
939 
940     /**
941      * Searches in this string for the index of the specified character. The
942      * search for the character starts at the specified offset and moves towards
943      * the end of this string.
944      *
945      * @param c
946      *            the character to find.
947      * @param start
948      *            the starting offset.
949      * @return the index in this string of the specified character, -1 if the
950      *         character isn't found.
951      */
indexOf(int c, int start)952     public int indexOf(int c, int start) {
953         if (c > 0xffff) {
954             return indexOfSupplementary(c, start);
955         }
956         return fastIndexOf(c, start);
957     }
958 
fastIndexOf(int c, int start)959     private native int fastIndexOf(int c, int start);
960 
indexOfSupplementary(int c, int start)961     private int indexOfSupplementary(int c, int start) {
962         if (!Character.isSupplementaryCodePoint(c)) {
963             return -1;
964         }
965         char[] chars = Character.toChars(c);
966         String needle = new String(0, chars.length, chars);
967         return indexOf(needle, start);
968     }
969 
970     /**
971      * Searches in this string for the first index of the specified string. The
972      * search for the string starts at the beginning and moves towards the end
973      * of this string.
974      *
975      * @param string
976      *            the string to find.
977      * @return the index of the first character of the specified string in this
978      *         string, -1 if the specified string is not a substring.
979      * @throws NullPointerException
980      *             if {@code string} is {@code null}.
981      */
indexOf(String string)982     public int indexOf(String string) {
983         int start = 0;
984         int subCount = string.count;
985         int _count = count;
986         if (subCount > 0) {
987             if (subCount > _count) {
988                 return -1;
989             }
990             char[] target = string.value;
991             int subOffset = string.offset;
992             char firstChar = target[subOffset];
993             int end = subOffset + subCount;
994             while (true) {
995                 int i = indexOf(firstChar, start);
996                 if (i == -1 || subCount + i > _count) {
997                     return -1; // handles subCount > count || start >= count
998                 }
999                 int o1 = offset + i, o2 = subOffset;
1000                 char[] _value = value;
1001                 while (++o2 < end && _value[++o1] == target[o2]) {
1002                     // Intentionally empty
1003                 }
1004                 if (o2 == end) {
1005                     return i;
1006                 }
1007                 start = i + 1;
1008             }
1009         }
1010         return start < _count ? start : _count;
1011     }
1012 
1013     /**
1014      * Searches in this string for the index of the specified string. The search
1015      * for the string starts at the specified offset and moves towards the end
1016      * of this string.
1017      *
1018      * @param subString
1019      *            the string to find.
1020      * @param start
1021      *            the starting offset.
1022      * @return the index of the first character of the specified string in this
1023      *         string, -1 if the specified string is not a substring.
1024      * @throws NullPointerException
1025      *             if {@code subString} is {@code null}.
1026      */
indexOf(String subString, int start)1027     public int indexOf(String subString, int start) {
1028         if (start < 0) {
1029             start = 0;
1030         }
1031         int subCount = subString.count;
1032         int _count = count;
1033         if (subCount > 0) {
1034             if (subCount + start > _count) {
1035                 return -1;
1036             }
1037             char[] target = subString.value;
1038             int subOffset = subString.offset;
1039             char firstChar = target[subOffset];
1040             int end = subOffset + subCount;
1041             while (true) {
1042                 int i = indexOf(firstChar, start);
1043                 if (i == -1 || subCount + i > _count) {
1044                     return -1; // handles subCount > count || start >= count
1045                 }
1046                 int o1 = offset + i, o2 = subOffset;
1047                 char[] _value = value;
1048                 while (++o2 < end && _value[++o1] == target[o2]) {
1049                     // Intentionally empty
1050                 }
1051                 if (o2 == end) {
1052                     return i;
1053                 }
1054                 start = i + 1;
1055             }
1056         }
1057         return start < _count ? start : _count;
1058     }
1059 
1060     /**
1061      * Returns an interned string equal to this string. The VM maintains an internal set of
1062      * unique strings. All string literals found in loaded classes'
1063      * constant pools are automatically interned. Manually-interned strings are only weakly
1064      * referenced, so calling {@code intern} won't lead to unwanted retention.
1065      *
1066      * <p>Interning is typically used because it guarantees that for interned strings
1067      * {@code a} and {@code b}, {@code a.equals(b)} can be simplified to
1068      * {@code a == b}. (This is not true of non-interned strings.)
1069      *
1070      * <p>Many applications find it simpler and more convenient to use an explicit
1071      * {@link java.util.HashMap} to implement their own pools.
1072      */
intern()1073     public native String intern();
1074 
1075     /**
1076      * Returns true if the length of this string is 0.
1077      *
1078      * @since 1.6
1079      */
isEmpty()1080     public native boolean isEmpty();
1081 
1082     /**
1083      * Returns the last index of the code point {@code c}, or -1.
1084      * The search for the character starts at the end and moves towards the
1085      * beginning of this string.
1086      */
lastIndexOf(int c)1087     public int lastIndexOf(int c) {
1088         if (c > 0xffff) {
1089             return lastIndexOfSupplementary(c, Integer.MAX_VALUE);
1090         }
1091         int _count = count;
1092         int _offset = offset;
1093         char[] _value = value;
1094         for (int i = _offset + _count - 1; i >= _offset; --i) {
1095             if (_value[i] == c) {
1096                 return i - _offset;
1097             }
1098         }
1099         return -1;
1100     }
1101 
1102     /**
1103      * Returns the last index of the code point {@code c}, or -1.
1104      * The search for the character starts at offset {@code start} and moves towards
1105      * the beginning of this string.
1106      */
lastIndexOf(int c, int start)1107     public int lastIndexOf(int c, int start) {
1108         if (c > 0xffff) {
1109             return lastIndexOfSupplementary(c, start);
1110         }
1111         int _count = count;
1112         int _offset = offset;
1113         char[] _value = value;
1114         if (start >= 0) {
1115             if (start >= _count) {
1116                 start = _count - 1;
1117             }
1118             for (int i = _offset + start; i >= _offset; --i) {
1119                 if (_value[i] == c) {
1120                     return i - _offset;
1121                 }
1122             }
1123         }
1124         return -1;
1125     }
1126 
lastIndexOfSupplementary(int c, int start)1127     private int lastIndexOfSupplementary(int c, int start) {
1128         if (!Character.isSupplementaryCodePoint(c)) {
1129             return -1;
1130         }
1131         char[] chars = Character.toChars(c);
1132         String needle = new String(0, chars.length, chars);
1133         return lastIndexOf(needle, start);
1134     }
1135 
1136     /**
1137      * Searches in this string for the last index of the specified string. The
1138      * search for the string starts at the end and moves towards the beginning
1139      * of this string.
1140      *
1141      * @param string
1142      *            the string to find.
1143      * @return the index of the first character of the specified string in this
1144      *         string, -1 if the specified string is not a substring.
1145      * @throws NullPointerException
1146      *             if {@code string} is {@code null}.
1147      */
lastIndexOf(String string)1148     public int lastIndexOf(String string) {
1149         // Use count instead of count - 1 so lastIndexOf("") returns count
1150         return lastIndexOf(string, count);
1151     }
1152 
1153     /**
1154      * Searches in this string for the index of the specified string. The search
1155      * for the string starts at the specified offset and moves towards the
1156      * beginning of this string.
1157      *
1158      * @param subString
1159      *            the string to find.
1160      * @param start
1161      *            the starting offset.
1162      * @return the index of the first character of the specified string in this
1163      *         string , -1 if the specified string is not a substring.
1164      * @throws NullPointerException
1165      *             if {@code subString} is {@code null}.
1166      */
lastIndexOf(String subString, int start)1167     public int lastIndexOf(String subString, int start) {
1168         int subCount = subString.count;
1169         if (subCount <= count && start >= 0) {
1170             if (subCount > 0) {
1171                 if (start > count - subCount) {
1172                     start = count - subCount;
1173                 }
1174                 // count and subCount are both >= 1
1175                 char[] target = subString.value;
1176                 int subOffset = subString.offset;
1177                 char firstChar = target[subOffset];
1178                 int end = subOffset + subCount;
1179                 while (true) {
1180                     int i = lastIndexOf(firstChar, start);
1181                     if (i == -1) {
1182                         return -1;
1183                     }
1184                     int o1 = offset + i, o2 = subOffset;
1185                     while (++o2 < end && value[++o1] == target[o2]) {
1186                         // Intentionally empty
1187                     }
1188                     if (o2 == end) {
1189                         return i;
1190                     }
1191                     start = i - 1;
1192                 }
1193             }
1194             return start < count ? start : count;
1195         }
1196         return -1;
1197     }
1198 
1199     /**
1200      * Returns the size of this string.
1201      *
1202      * @return the number of characters in this string.
1203      */
length()1204     public native int length();
1205 
1206     /**
1207      * Compares the specified string to this string and compares the specified
1208      * range of characters to determine if they are the same.
1209      *
1210      * @param thisStart
1211      *            the starting offset in this string.
1212      * @param string
1213      *            the string to compare.
1214      * @param start
1215      *            the starting offset in the specified string.
1216      * @param length
1217      *            the number of characters to compare.
1218      * @return {@code true} if the ranges of characters are equal, {@code false}
1219      *         otherwise
1220      * @throws NullPointerException
1221      *             if {@code string} is {@code null}.
1222      */
regionMatches(int thisStart, String string, int start, int length)1223     public boolean regionMatches(int thisStart, String string, int start, int length) {
1224         if (string == null) {
1225             throw new NullPointerException("string == null");
1226         }
1227         if (start < 0 || string.count - start < length) {
1228             return false;
1229         }
1230         if (thisStart < 0 || count - thisStart < length) {
1231             return false;
1232         }
1233         if (length <= 0) {
1234             return true;
1235         }
1236         int o1 = offset + thisStart, o2 = string.offset + start;
1237         char[] value1 = value;
1238         char[] value2 = string.value;
1239         for (int i = 0; i < length; ++i) {
1240             if (value1[o1 + i] != value2[o2 + i]) {
1241                 return false;
1242             }
1243         }
1244         return true;
1245     }
1246 
1247     /**
1248      * Compares the specified string to this string and compares the specified
1249      * range of characters to determine if they are the same. When ignoreCase is
1250      * true, the case of the characters is ignored during the comparison.
1251      *
1252      * @param ignoreCase
1253      *            specifies if case should be ignored.
1254      * @param thisStart
1255      *            the starting offset in this string.
1256      * @param string
1257      *            the string to compare.
1258      * @param start
1259      *            the starting offset in the specified string.
1260      * @param length
1261      *            the number of characters to compare.
1262      * @return {@code true} if the ranges of characters are equal, {@code false}
1263      *         otherwise.
1264      * @throws NullPointerException
1265      *             if {@code string} is {@code null}.
1266      */
regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length)1267     public boolean regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length) {
1268         if (!ignoreCase) {
1269             return regionMatches(thisStart, string, start, length);
1270         }
1271         if (string == null) {
1272             throw new NullPointerException("string == null");
1273         }
1274         if (thisStart < 0 || length > count - thisStart) {
1275             return false;
1276         }
1277         if (start < 0 || length > string.count - start) {
1278             return false;
1279         }
1280         thisStart += offset;
1281         start += string.offset;
1282         int end = thisStart + length;
1283         char[] target = string.value;
1284         while (thisStart < end) {
1285             char c1 = value[thisStart++];
1286             char c2 = target[start++];
1287             if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
1288                 return false;
1289             }
1290         }
1291         return true;
1292     }
1293 
1294     /**
1295      * Copies this string replacing occurrences of the specified character with
1296      * another character.
1297      *
1298      * @param oldChar
1299      *            the character to replace.
1300      * @param newChar
1301      *            the replacement character.
1302      * @return a new string with occurrences of oldChar replaced by newChar.
1303      */
replace(char oldChar, char newChar)1304     public String replace(char oldChar, char newChar) {
1305         char[] buffer = value;
1306         int _offset = offset;
1307         int _count = count;
1308 
1309         int idx = _offset;
1310         int last = _offset + _count;
1311         boolean copied = false;
1312         while (idx < last) {
1313             if (buffer[idx] == oldChar) {
1314                 if (!copied) {
1315                     char[] newBuffer = new char[_count];
1316                     System.arraycopy(buffer, _offset, newBuffer, 0, _count);
1317                     buffer = newBuffer;
1318                     idx -= _offset;
1319                     last -= _offset;
1320                     copied = true;
1321                 }
1322                 buffer[idx] = newChar;
1323             }
1324             idx++;
1325         }
1326 
1327         return copied ? new String(0, count, buffer) : this;
1328     }
1329 
1330     /**
1331      * Copies this string replacing occurrences of the specified target sequence
1332      * with another sequence. The string is processed from the beginning to the
1333      * end.
1334      *
1335      * @param target
1336      *            the sequence to replace.
1337      * @param replacement
1338      *            the replacement sequence.
1339      * @return the resulting string.
1340      * @throws NullPointerException
1341      *             if {@code target} or {@code replacement} is {@code null}.
1342      */
replace(CharSequence target, CharSequence replacement)1343     public String replace(CharSequence target, CharSequence replacement) {
1344         if (target == null) {
1345             throw new NullPointerException("target == null");
1346         }
1347         if (replacement == null) {
1348             throw new NullPointerException("replacement == null");
1349         }
1350 
1351         String targetString = target.toString();
1352         int matchStart = indexOf(targetString, 0);
1353         if (matchStart == -1) {
1354             // If there's nothing to replace, return the original string untouched.
1355             return this;
1356         }
1357 
1358         String replacementString = replacement.toString();
1359 
1360         // The empty target matches at the start and end and between each character.
1361         int targetLength = targetString.length();
1362         if (targetLength == 0) {
1363             int resultLength = (count + 2) * replacementString.length();
1364             StringBuilder result = new StringBuilder(resultLength);
1365             result.append(replacementString);
1366             for (int i = offset; i < count; ++i) {
1367                 result.append(value[i]);
1368                 result.append(replacementString);
1369             }
1370             return result.toString();
1371         }
1372 
1373         StringBuilder result = new StringBuilder(count);
1374         int searchStart = 0;
1375         do {
1376             // Copy characters before the match...
1377             result.append(value, offset + searchStart, matchStart - searchStart);
1378             // Insert the replacement...
1379             result.append(replacementString);
1380             // And skip over the match...
1381             searchStart = matchStart + targetLength;
1382         } while ((matchStart = indexOf(targetString, searchStart)) != -1);
1383         // Copy any trailing chars...
1384         result.append(value, offset + searchStart, count - searchStart);
1385         return result.toString();
1386     }
1387 
1388     /**
1389      * Compares the specified string to this string to determine if the
1390      * specified string is a prefix.
1391      *
1392      * @param prefix
1393      *            the string to look for.
1394      * @return {@code true} if the specified string is a prefix of this string,
1395      *         {@code false} otherwise
1396      * @throws NullPointerException
1397      *             if {@code prefix} is {@code null}.
1398      */
startsWith(String prefix)1399     public boolean startsWith(String prefix) {
1400         return startsWith(prefix, 0);
1401     }
1402 
1403     /**
1404      * Compares the specified string to this string, starting at the specified
1405      * offset, to determine if the specified string is a prefix.
1406      *
1407      * @param prefix
1408      *            the string to look for.
1409      * @param start
1410      *            the starting offset.
1411      * @return {@code true} if the specified string occurs in this string at the
1412      *         specified offset, {@code false} otherwise.
1413      * @throws NullPointerException
1414      *             if {@code prefix} is {@code null}.
1415      */
startsWith(String prefix, int start)1416     public boolean startsWith(String prefix, int start) {
1417         return regionMatches(start, prefix, 0, prefix.count);
1418     }
1419 
1420     /**
1421      * Returns a string containing a suffix of this string. The returned string
1422      * shares this string's <a href="#backing_array">backing array</a>.
1423      *
1424      * @param start
1425      *            the offset of the first character.
1426      * @return a new string containing the characters from start to the end of
1427      *         the string.
1428      * @throws IndexOutOfBoundsException
1429      *             if {@code start < 0} or {@code start > length()}.
1430      */
substring(int start)1431     public String substring(int start) {
1432         if (start == 0) {
1433             return this;
1434         }
1435         if (start >= 0 && start <= count) {
1436             return new String(offset + start, count - start, value);
1437         }
1438         throw indexAndLength(start);
1439     }
1440 
1441     /**
1442      * Returns a string containing a subsequence of characters from this string.
1443      * The returned string shares this string's <a href="#backing_array">backing
1444      * array</a>.
1445      *
1446      * @param start
1447      *            the offset of the first character.
1448      * @param end
1449      *            the offset one past the last character.
1450      * @return a new string containing the characters from start to end - 1
1451      * @throws IndexOutOfBoundsException
1452      *             if {@code start < 0}, {@code start > end} or {@code end >
1453      *             length()}.
1454      */
substring(int start, int end)1455     public String substring(int start, int end) {
1456         if (start == 0 && end == count) {
1457             return this;
1458         }
1459         // NOTE last character not copied!
1460         // Fast range check.
1461         if (start >= 0 && start <= end && end <= count) {
1462             return new String(offset + start, end - start, value);
1463         }
1464         throw startEndAndLength(start, end);
1465     }
1466 
1467     /**
1468      * Copies the characters in this string to a character array.
1469      *
1470      * @return a character array containing the characters of this string.
1471      */
toCharArray()1472     public char[] toCharArray() {
1473         char[] buffer = new char[count];
1474         System.arraycopy(value, offset, buffer, 0, count);
1475         return buffer;
1476     }
1477 
1478     /**
1479      * Converts this string to lower case, using the rules of the user's default locale.
1480      * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
1481      *
1482      * @return a new lower case string, or {@code this} if it's already all lower case.
1483      */
toLowerCase()1484     public String toLowerCase() {
1485         return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count);
1486     }
1487 
1488     /**
1489      * Converts this string to lower case, using the rules of {@code locale}.
1490      *
1491      * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
1492      * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
1493      * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
1494      * correct case mapping of Greek characters: any locale will do.
1495      *
1496      * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
1497      * for full details of context- and language-specific special cases.
1498      *
1499      * @return a new lower case string, or {@code this} if it's already all lower case.
1500      */
toLowerCase(Locale locale)1501     public String toLowerCase(Locale locale) {
1502         return CaseMapper.toLowerCase(locale, this, value, offset, count);
1503     }
1504 
1505     /**
1506      * Returns this string.
1507      */
1508     @Override
toString()1509     public String toString() {
1510         return this;
1511     }
1512 
1513     /**
1514      * Converts this this string to upper case, using the rules of the user's default locale.
1515      * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
1516      *
1517      * @return a new upper case string, or {@code this} if it's already all upper case.
1518      */
toUpperCase()1519     public String toUpperCase() {
1520         return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count);
1521     }
1522 
1523     /**
1524      * Converts this this string to upper case, using the rules of {@code locale}.
1525      *
1526      * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
1527      * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
1528      * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
1529      * correct case mapping of Greek characters: any locale will do.
1530      *
1531      * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
1532      * for full details of context- and language-specific special cases.
1533      *
1534      * @return a new upper case string, or {@code this} if it's already all upper case.
1535      */
toUpperCase(Locale locale)1536     public String toUpperCase(Locale locale) {
1537         return CaseMapper.toUpperCase(locale, this, value, offset, count);
1538     }
1539 
1540     /**
1541      * Copies this string removing white space characters from the beginning and
1542      * end of the string.
1543      *
1544      * @return a new string with characters <code><= \\u0020</code> removed from
1545      *         the beginning and the end.
1546      */
trim()1547     public String trim() {
1548         int start = offset, last = offset + count - 1;
1549         int end = last;
1550         while ((start <= end) && (value[start] <= ' ')) {
1551             start++;
1552         }
1553         while ((end >= start) && (value[end] <= ' ')) {
1554             end--;
1555         }
1556         if (start == offset && end == last) {
1557             return this;
1558         }
1559         return new String(start, end - start + 1, value);
1560     }
1561 
1562     /**
1563      * Creates a new string containing the characters in the specified character
1564      * array. Modifying the character array after creating the string has no
1565      * effect on the string.
1566      *
1567      * @param data
1568      *            the array of characters.
1569      * @return the new string.
1570      * @throws NullPointerException
1571      *             if {@code data} is {@code null}.
1572      */
valueOf(char[] data)1573     public static String valueOf(char[] data) {
1574         return new String(data, 0, data.length);
1575     }
1576 
1577     /**
1578      * Creates a new string containing the specified characters in the character
1579      * array. Modifying the character array after creating the string has no
1580      * effect on the string.
1581      *
1582      * @param data
1583      *            the array of characters.
1584      * @param start
1585      *            the starting offset in the character array.
1586      * @param length
1587      *            the number of characters to use.
1588      * @return the new string.
1589      * @throws IndexOutOfBoundsException
1590      *             if {@code length < 0}, {@code start < 0} or {@code start +
1591      *             length > data.length}
1592      * @throws NullPointerException
1593      *             if {@code data} is {@code null}.
1594      */
valueOf(char[] data, int start, int length)1595     public static String valueOf(char[] data, int start, int length) {
1596         return new String(data, start, length);
1597     }
1598 
1599     /**
1600      * Converts the specified character to its string representation.
1601      *
1602      * @param value
1603      *            the character.
1604      * @return the character converted to a string.
1605      */
valueOf(char value)1606     public static String valueOf(char value) {
1607         String s;
1608         if (value < 128) {
1609             s = new String(value, 1, ASCII);
1610         } else {
1611             s = new String(0, 1, new char[] { value });
1612         }
1613         s.hashCode = value;
1614         return s;
1615     }
1616 
1617     /**
1618      * Converts the specified double to its string representation.
1619      *
1620      * @param value
1621      *            the double.
1622      * @return the double converted to a string.
1623      */
valueOf(double value)1624     public static String valueOf(double value) {
1625         return Double.toString(value);
1626     }
1627 
1628     /**
1629      * Converts the specified float to its string representation.
1630      *
1631      * @param value
1632      *            the float.
1633      * @return the float converted to a string.
1634      */
valueOf(float value)1635     public static String valueOf(float value) {
1636         return Float.toString(value);
1637     }
1638 
1639     /**
1640      * Converts the specified integer to its string representation.
1641      *
1642      * @param value
1643      *            the integer.
1644      * @return the integer converted to a string.
1645      */
valueOf(int value)1646     public static String valueOf(int value) {
1647         return Integer.toString(value);
1648     }
1649 
1650     /**
1651      * Converts the specified long to its string representation.
1652      *
1653      * @param value
1654      *            the long.
1655      * @return the long converted to a string.
1656      */
valueOf(long value)1657     public static String valueOf(long value) {
1658         return Long.toString(value);
1659     }
1660 
1661     /**
1662      * Converts the specified object to its string representation. If the object
1663      * is null return the string {@code "null"}, otherwise use {@code
1664      * toString()} to get the string representation.
1665      *
1666      * @param value
1667      *            the object.
1668      * @return the object converted to a string, or the string {@code "null"}.
1669      */
valueOf(Object value)1670     public static String valueOf(Object value) {
1671         return value != null ? value.toString() : "null";
1672     }
1673 
1674     /**
1675      * Converts the specified boolean to its string representation. When the
1676      * boolean is {@code true} return {@code "true"}, otherwise return {@code
1677      * "false"}.
1678      *
1679      * @param value
1680      *            the boolean.
1681      * @return the boolean converted to a string.
1682      */
valueOf(boolean value)1683     public static String valueOf(boolean value) {
1684         return value ? "true" : "false";
1685     }
1686 
1687     /**
1688      * Returns whether the characters in the StringBuffer {@code strbuf} are the
1689      * same as those in this string.
1690      *
1691      * @param strbuf
1692      *            the StringBuffer to compare this string to.
1693      * @return {@code true} if the characters in {@code strbuf} are identical to
1694      *         those in this string. If they are not, {@code false} will be
1695      *         returned.
1696      * @throws NullPointerException
1697      *             if {@code strbuf} is {@code null}.
1698      * @since 1.4
1699      */
contentEquals(StringBuffer strbuf)1700     public boolean contentEquals(StringBuffer strbuf) {
1701         synchronized (strbuf) {
1702             int size = strbuf.length();
1703             if (count != size) {
1704                 return false;
1705             }
1706             return regionMatches(0, new String(0, size, strbuf.getValue()), 0,
1707                     size);
1708         }
1709     }
1710 
1711     /**
1712      * Compares a {@code CharSequence} to this {@code String} to determine if
1713      * their contents are equal.
1714      *
1715      * @param cs
1716      *            the character sequence to compare to.
1717      * @return {@code true} if equal, otherwise {@code false}
1718      * @since 1.5
1719      */
contentEquals(CharSequence cs)1720     public boolean contentEquals(CharSequence cs) {
1721         if (cs == null) {
1722             throw new NullPointerException("cs == null");
1723         }
1724 
1725         int len = cs.length();
1726 
1727         if (len != count) {
1728             return false;
1729         }
1730 
1731         if (len == 0 && count == 0) {
1732             return true; // since both are empty strings
1733         }
1734 
1735         return regionMatches(0, cs.toString(), 0, len);
1736     }
1737 
1738     /**
1739      * Tests whether this string matches the given {@code regularExpression}. This method returns
1740      * true only if the regular expression matches the <i>entire</i> input string. A common mistake is
1741      * to assume that this method behaves like {@link #contains}; if you want to match anywhere
1742      * within the input string, you need to add {@code .*} to the beginning and end of your
1743      * regular expression. See {@link Pattern#matches}.
1744      *
1745      * <p>If the same regular expression is to be used for multiple operations, it may be more
1746      * efficient to reuse a compiled {@code Pattern}.
1747      *
1748      * @throws PatternSyntaxException
1749      *             if the syntax of the supplied regular expression is not
1750      *             valid.
1751      * @throws NullPointerException if {@code regularExpression == null}
1752      * @since 1.4
1753      */
matches(String regularExpression)1754     public boolean matches(String regularExpression) {
1755         return Pattern.matches(regularExpression, this);
1756     }
1757 
1758     /**
1759      * Replaces all matches for {@code regularExpression} within this string with the given
1760      * {@code replacement}.
1761      * See {@link Pattern} for regular expression syntax.
1762      *
1763      * <p>If the same regular expression is to be used for multiple operations, it may be more
1764      * efficient to reuse a compiled {@code Pattern}.
1765      *
1766      * @throws PatternSyntaxException
1767      *             if the syntax of the supplied regular expression is not
1768      *             valid.
1769      * @throws NullPointerException if {@code regularExpression == null}
1770      * @see Pattern
1771      * @since 1.4
1772      */
replaceAll(String regularExpression, String replacement)1773     public String replaceAll(String regularExpression, String replacement) {
1774         return Pattern.compile(regularExpression).matcher(this).replaceAll(replacement);
1775     }
1776 
1777     /**
1778      * Replaces the first match for {@code regularExpression} within this string with the given
1779      * {@code replacement}.
1780      * See {@link Pattern} for regular expression syntax.
1781      *
1782      * <p>If the same regular expression is to be used for multiple operations, it may be more
1783      * efficient to reuse a compiled {@code Pattern}.
1784      *
1785      * @throws PatternSyntaxException
1786      *             if the syntax of the supplied regular expression is not
1787      *             valid.
1788      * @throws NullPointerException if {@code regularExpression == null}
1789      * @see Pattern
1790      * @since 1.4
1791      */
replaceFirst(String regularExpression, String replacement)1792     public String replaceFirst(String regularExpression, String replacement) {
1793         return Pattern.compile(regularExpression).matcher(this).replaceFirst(replacement);
1794     }
1795 
1796     /**
1797      * Splits this string using the supplied {@code regularExpression}.
1798      * Equivalent to {@code split(regularExpression, 0)}.
1799      * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
1800      * See {@link Pattern} for regular expression syntax.
1801      *
1802      * <p>If the same regular expression is to be used for multiple operations, it may be more
1803      * efficient to reuse a compiled {@code Pattern}.
1804      *
1805      * @throws NullPointerException if {@code regularExpression ==  null}
1806      * @throws PatternSyntaxException
1807      *             if the syntax of the supplied regular expression is not
1808      *             valid.
1809      * @see Pattern
1810      * @since 1.4
1811      */
split(String regularExpression)1812     public String[] split(String regularExpression) {
1813         return split(regularExpression, 0);
1814     }
1815 
1816     /**
1817      * Splits this string using the supplied {@code regularExpression}.
1818      * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
1819      * See {@link Pattern} for regular expression syntax.
1820      *
1821      * <p>If the same regular expression is to be used for multiple operations, it may be more
1822      * efficient to reuse a compiled {@code Pattern}.
1823      *
1824      * @throws NullPointerException if {@code regularExpression ==  null}
1825      * @throws PatternSyntaxException
1826      *             if the syntax of the supplied regular expression is not
1827      *             valid.
1828      * @since 1.4
1829      */
split(String regularExpression, int limit)1830     public String[] split(String regularExpression, int limit) {
1831         String[] result = java.util.regex.Splitter.fastSplit(regularExpression, this, limit);
1832         return result != null ? result : Pattern.compile(regularExpression).split(this, limit);
1833     }
1834 
1835     /**
1836      * Has the same result as the substring function, but is present so that
1837      * string may implement the CharSequence interface.
1838      *
1839      * @param start
1840      *            the offset the first character.
1841      * @param end
1842      *            the offset of one past the last character to include.
1843      * @return the subsequence requested.
1844      * @throws IndexOutOfBoundsException
1845      *             if {@code start < 0}, {@code end < 0}, {@code start > end} or
1846      *             {@code end > length()}.
1847      * @see java.lang.CharSequence#subSequence(int, int)
1848      * @since 1.4
1849      */
subSequence(int start, int end)1850     public CharSequence subSequence(int start, int end) {
1851         return substring(start, end);
1852     }
1853 
1854     /**
1855      * Returns the Unicode code point at the given {@code index}.
1856      *
1857      * @throws IndexOutOfBoundsException if {@code index < 0 || index >= length()}
1858      * @see Character#codePointAt(char[], int, int)
1859      * @since 1.5
1860      */
codePointAt(int index)1861     public int codePointAt(int index) {
1862         if (index < 0 || index >= count) {
1863             throw indexAndLength(index);
1864         }
1865         return Character.codePointAt(value, offset + index, offset + count);
1866     }
1867 
1868     /**
1869      * Returns the Unicode code point that precedes the given {@code index}.
1870      *
1871      * @throws IndexOutOfBoundsException if {@code index < 1 || index > length()}
1872      * @see Character#codePointBefore(char[], int, int)
1873      * @since 1.5
1874      */
codePointBefore(int index)1875     public int codePointBefore(int index) {
1876         if (index < 1 || index > count) {
1877             throw indexAndLength(index);
1878         }
1879         return Character.codePointBefore(value, offset + index, offset);
1880     }
1881 
1882     /**
1883      * Calculates the number of Unicode code points between {@code start}
1884      * and {@code end}.
1885      *
1886      * @param start
1887      *            the inclusive beginning index of the subsequence.
1888      * @param end
1889      *            the exclusive end index of the subsequence.
1890      * @return the number of Unicode code points in the subsequence.
1891      * @throws IndexOutOfBoundsException
1892      *         if {@code start < 0 || end > length() || start > end}
1893      * @see Character#codePointCount(CharSequence, int, int)
1894      * @since 1.5
1895      */
codePointCount(int start, int end)1896     public int codePointCount(int start, int end) {
1897         if (start < 0 || end > count || start > end) {
1898             throw startEndAndLength(start, end);
1899         }
1900         return Character.codePointCount(value, offset + start, end - start);
1901     }
1902 
1903     /**
1904      * Determines if this {@code String} contains the sequence of characters in
1905      * the {@code CharSequence} passed.
1906      *
1907      * @param cs
1908      *            the character sequence to search for.
1909      * @return {@code true} if the sequence of characters are contained in this
1910      *         string, otherwise {@code false}.
1911      * @since 1.5
1912      */
contains(CharSequence cs)1913     public boolean contains(CharSequence cs) {
1914         if (cs == null) {
1915             throw new NullPointerException("cs == null");
1916         }
1917         return indexOf(cs.toString()) >= 0;
1918     }
1919 
1920     /**
1921      * Returns the index within this object that is offset from {@code index} by
1922      * {@code codePointOffset} code points.
1923      *
1924      * @param index
1925      *            the index within this object to calculate the offset from.
1926      * @param codePointOffset
1927      *            the number of code points to count.
1928      * @return the index within this object that is the offset.
1929      * @throws IndexOutOfBoundsException
1930      *             if {@code index} is negative or greater than {@code length()}
1931      *             or if there aren't enough code points before or after {@code
1932      *             index} to match {@code codePointOffset}.
1933      * @since 1.5
1934      */
offsetByCodePoints(int index, int codePointOffset)1935     public int offsetByCodePoints(int index, int codePointOffset) {
1936         int s = index + offset;
1937         int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset);
1938         return r - offset;
1939     }
1940 
1941     /**
1942      * Returns a localized formatted string, using the supplied format and arguments,
1943      * using the user's default locale.
1944      *
1945      * <p>If you're formatting a string other than for human
1946      * consumption, you should use the {@code format(Locale, String, Object...)}
1947      * overload and supply {@code Locale.US}. See
1948      * "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
1949      *
1950      * @param format the format string (see {@link java.util.Formatter#format})
1951      * @param args
1952      *            the list of arguments passed to the formatter. If there are
1953      *            more arguments than required by {@code format},
1954      *            additional arguments are ignored.
1955      * @return the formatted string.
1956      * @throws NullPointerException if {@code format == null}
1957      * @throws java.util.IllegalFormatException
1958      *             if the format is invalid.
1959      * @since 1.5
1960      */
format(String format, Object... args)1961     public static String format(String format, Object... args) {
1962         return format(Locale.getDefault(), format, args);
1963     }
1964 
1965     /**
1966      * Returns a formatted string, using the supplied format and arguments,
1967      * localized to the given locale.
1968      *
1969      * @param locale
1970      *            the locale to apply; {@code null} value means no localization.
1971      * @param format the format string (see {@link java.util.Formatter#format})
1972      * @param args
1973      *            the list of arguments passed to the formatter. If there are
1974      *            more arguments than required by {@code format},
1975      *            additional arguments are ignored.
1976      * @return the formatted string.
1977      * @throws NullPointerException if {@code format == null}
1978      * @throws java.util.IllegalFormatException
1979      *             if the format is invalid.
1980      * @since 1.5
1981      */
format(Locale locale, String format, Object... args)1982     public static String format(Locale locale, String format, Object... args) {
1983         if (format == null) {
1984             throw new NullPointerException("format == null");
1985         }
1986         int bufferSize = format.length() + (args == null ? 0 : args.length * 10);
1987         Formatter f = new Formatter(new StringBuilder(bufferSize), locale);
1988         return f.format(format, args).toString();
1989     }
1990 
1991     /*
1992      * An implementation of a String.indexOf that is supposed to perform
1993      * substantially better than the default algorithm if the "needle" (the
1994      * subString being searched for) is a constant string.
1995      *
1996      * For example, a JIT, upon encountering a call to String.indexOf(String),
1997      * where the needle is a constant string, may compute the values cache, md2
1998      * and lastChar, and change the call to the following method.
1999      */
2000     @FindBugsSuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD")
2001     @SuppressWarnings("unused")
indexOf(String haystackString, String needleString, int cache, int md2, char lastChar)2002     private static int indexOf(String haystackString, String needleString,
2003             int cache, int md2, char lastChar) {
2004         char[] haystack = haystackString.value;
2005         int haystackOffset = haystackString.offset;
2006         int haystackLength = haystackString.count;
2007         char[] needle = needleString.value;
2008         int needleOffset = needleString.offset;
2009         int needleLength = needleString.count;
2010         int needleLengthMinus1 = needleLength - 1;
2011         int haystackEnd = haystackOffset + haystackLength;
2012         outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) {
2013             if (lastChar == haystack[i]) {
2014                 for (int j = 0; j < needleLengthMinus1; ++j) {
2015                     if (needle[j + needleOffset] != haystack[i + j
2016                             - needleLengthMinus1]) {
2017                         int skip = 1;
2018                         if ((cache & (1 << haystack[i])) == 0) {
2019                             skip += j;
2020                         }
2021                         i += Math.max(md2, skip);
2022                         continue outer_loop;
2023                     }
2024                 }
2025                 return i - needleLengthMinus1 - haystackOffset;
2026             }
2027 
2028             if ((cache & (1 << haystack[i])) == 0) {
2029                 i += needleLengthMinus1;
2030             }
2031             i++;
2032         }
2033         return -1;
2034     }
2035 }
2036