      1 /*
      2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25
     26 package java.lang;
     27
     28 import jdk.internal.HotSpotIntrinsicCandidate;
     29
     30 /**
     31  * A mutable sequence of characters.  This class provides an API compatible
     32  * with {@code StringBuffer}, but with no guarantee of synchronization.
     33  * This class is designed for use as a drop-in replacement for
     34  * {@code StringBuffer} in places where the string buffer was being
     35  * used by a single thread (as is generally the case).   Where possible,
     36  * it is recommended that this class be used in preference to
     37  * {@code StringBuffer} as it will be faster under most implementations.
     38  *
     39  * <p>The principal operations on a {@code StringBuilder} are the
     40  * {@code append} and {@code insert} methods, which are
     41  * overloaded so as to accept data of any type. Each effectively
     42  * converts a given datum to a string and then appends or inserts the
     43  * characters of that string to the string builder. The
     44  * {@code append} method always adds these characters at the end
     45  * of the builder; the {@code insert} method adds the characters at
     46  * a specified point.
     47  * <p>
     48  * For example, if {@code z} refers to a string builder object
     49  * whose current contents are "{@code start}", then
     50  * the method call {@code z.append("le")} would cause the string
     51  * builder to contain "{@code startle}", whereas
     52  * {@code z.insert(4, "le")} would alter the string builder to
     53  * contain "{@code starlet}".
     54  * <p>
     55  * In general, if sb refers to an instance of a {@code StringBuilder},
     56  * then {@code sb.append(x)} has the same effect as
     57  * {@code sb.insert(sb.length(), x)}.
     58  * <p>
     59  * Every string builder has a capacity. As long as the length of the
     60  * character sequence contained in the string builder does not exceed
     61  * the capacity, it is not necessary to allocate a new internal
     62  * buffer. If the internal buffer overflows, it is automatically made larger.
     63  *
     64  * <p>Instances of {@code StringBuilder} are not safe for
     65  * use by multiple threads. If such synchronization is required then it is
     66  * recommended that {@link java.lang.StringBuffer} be used.
     67  *
     68  * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
     69  * or method in this class will cause a {@link NullPointerException} to be
     70  * thrown.
     71  *
     72  * @apiNote
     73  * {@code StringBuilder} implements {@code Comparable} but does not override
     74  * {@link Object#equals equals}. Thus, the natural ordering of {@code StringBuilder}
     75  * is inconsistent with equals. Care should be exercised if {@code StringBuilder}
     76  * objects are used as keys in a {@code SortedMap} or elements in a {@code SortedSet}.
     77  * See {@link Comparable}, {@link java.util.SortedMap SortedMap}, or
     78  * {@link java.util.SortedSet SortedSet} for more information.
     79  *
     80  * @author      Michael McCloskey
     81  * @see         java.lang.StringBuffer
     82  * @see         java.lang.String
     83  * @since       1.5
     84  */
     85 public final class StringBuilder
     86     extends AbstractStringBuilder
     87     implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
     88 {
     89
     90     /** use serialVersionUID for interoperability */
     91     @java.io.Serial
     92     static final long serialVersionUID = 4383685877147921099L;
     93
     94     /**
     95      * Constructs a string builder with no characters in it and an
     96      * initial capacity of 16 characters.
     97      */
     98     @HotSpotIntrinsicCandidate
     99     public StringBuilder() {
    100         super(16);
    101     }
    102
    103     /**
    104      * Constructs a string builder with no characters in it and an
    105      * initial capacity specified by the {@code capacity} argument.
    106      *
    107      * @param      capacity  the initial capacity.
    108      * @throws     NegativeArraySizeException  if the {@code capacity}
    109      *               argument is less than {@code 0}.
    110      */
    111     @HotSpotIntrinsicCandidate
    112     public StringBuilder(int capacity) {
    113         super(capacity);
    114     }
    115
    116     /**
    117      * Constructs a string builder initialized to the contents of the
    118      * specified string. The initial capacity of the string builder is
    119      * {@code 16} plus the length of the string argument.
    120      *
    121      * @param   str   the initial contents of the buffer.
    122      */
    123     @HotSpotIntrinsicCandidate
    124     public StringBuilder(String str) {
    125         super(str);
    126     }
    127
    128     /**
    129      * Constructs a string builder that contains the same characters
    130      * as the specified {@code CharSequence}. The initial capacity of
    131      * the string builder is {@code 16} plus the length of the
    132      * {@code CharSequence} argument.
    133      *
    134      * @param      seq   the sequence to copy.
    135      */
    136     public StringBuilder(CharSequence seq) {
    137         super(seq);
    138     }
    139
    140     /**
    141      * Compares two {@code StringBuilder} instances lexicographically. This method
    142      * follows the same rules for lexicographical comparison as defined in the
    143      * {@linkplain java.lang.CharSequence#compare(java.lang.CharSequence,
    144      * java.lang.CharSequence)  CharSequence.compare(this, another)} method.
    145      *
    146      * <p>
    147      * For finer-grained, locale-sensitive String comparison, refer to
    148      * {@link java.text.Collator}.
    149      *
    150      * @param another the {@code StringBuilder} to be compared with
    151      *
    152      * @return  the value {@code 0} if this {@code StringBuilder} contains the same
    153      * character sequence as that of the argument {@code StringBuilder}; a negative integer
    154      * if this {@code StringBuilder} is lexicographically less than the
    155      * {@code StringBuilder} argument; or a positive integer if this {@code StringBuilder}
    156      * is lexicographically greater than the {@code StringBuilder} argument.
    157      *
    158      * @since 11
    159      */
    160     @Override
    161     public int compareTo(StringBuilder another) {
    162         return super.compareTo(another);
    163     }
    164
    165     @Override
    166     public StringBuilder append(Object obj) {
    167         return append(String.valueOf(obj));
    168     }
    169
    170     @Override
    171     @HotSpotIntrinsicCandidate
    172     public StringBuilder append(String str) {
    173         super.append(str);
    174         return this;
    175     }
    176
    177     /**
    178      * Appends the specified {@code StringBuffer} to this sequence.
    179      * <p>
    180      * The characters of the {@code StringBuffer} argument are appended,
    181      * in order, to this sequence, increasing the
    182      * length of this sequence by the length of the argument.
    183      * If {@code sb} is {@code null}, then the four characters
    184      * {@code "null"} are appended to this sequence.
    185      * <p>
    186      * Let <i>n</i> be the length of this character sequence just prior to
    187      * execution of the {@code append} method. Then the character at index
    188      * <i>k</i> in the new character sequence is equal to the character at
    189      * index <i>k</i> in the old character sequence, if <i>k</i> is less than
    190      * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
    191      * in the argument {@code sb}.
    192      *
    193      * @param   sb   the {@code StringBuffer} to append.
    194      * @return  a reference to this object.
    195      */
    196     public StringBuilder append(StringBuffer sb) {
    197         super.append(sb);
    198         return this;
    199     }
    200
    201     @Override
    202     public StringBuilder append(CharSequence s) {
    203         super.append(s);
    204         return this;
    205     }
    206
    207     /**
    208      * @throws     IndexOutOfBoundsException {@inheritDoc}
    209      */
    210     @Override
    211     public StringBuilder append(CharSequence s, int start, int end) {
    212         super.append(s, start, end);
    213         return this;
    214     }
    215
    216     @Override
    217     public StringBuilder append(char[] str) {
    218         super.append(str);
    219         return this;
    220     }
    221
    222     /**
    223      * @throws IndexOutOfBoundsException {@inheritDoc}
    224      */
    225     @Override
    226     public StringBuilder append(char[] str, int offset, int len) {
    227         super.append(str, offset, len);
    228         return this;
    229     }
    230
    231     @Override
    232     public StringBuilder append(boolean b) {
    233         super.append(b);
    234         return this;
    235     }
    236
    237     @Override
    238     @HotSpotIntrinsicCandidate
    239     public StringBuilder append(char c) {
    240         super.append(c);
    241         return this;
    242     }
    243
    244     @Override
    245     @HotSpotIntrinsicCandidate
    246     public StringBuilder append(int i) {
    247         super.append(i);
    248         return this;
    249     }
    250
    251     @Override
    252     public StringBuilder append(long lng) {
    253         super.append(lng);
    254         return this;
    255     }
    256
    257     @Override
    258     public StringBuilder append(float f) {
    259         super.append(f);
    260         return this;
    261     }
    262
    263     @Override
    264     public StringBuilder append(double d) {
    265         super.append(d);
    266         return this;
    267     }
    268
    269     /**
    270      * @since 1.5
    271      */
    272     @Override
    273     public StringBuilder appendCodePoint(int codePoint) {
    274         super.appendCodePoint(codePoint);
    275         return this;
    276     }
    277
    278     /**
    279      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    280      */
    281     @Override
    282     public StringBuilder delete(int start, int end) {
    283         super.delete(start, end);
    284         return this;
    285     }
    286
    287     /**
    288      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    289      */
    290     @Override
    291     public StringBuilder deleteCharAt(int index) {
    292         super.deleteCharAt(index);
    293         return this;
    294     }
    295
    296     /**
    297      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    298      */
    299     @Override
    300     public StringBuilder replace(int start, int end, String str) {
    301         super.replace(start, end, str);
    302         return this;
    303     }
    304
    305     /**
    306      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    307      */
    308     @Override
    309     public StringBuilder insert(int index, char[] str, int offset,
    310                                 int len)
    311     {
    312         super.insert(index, str, offset, len);
    313         return this;
    314     }
    315
    316     /**
    317      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    318      */
    319     @Override
    320     public StringBuilder insert(int offset, Object obj) {
    321             super.insert(offset, obj);
    322             return this;
    323     }
    324
    325     /**
    326      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    327      */
    328     @Override
    329     public StringBuilder insert(int offset, String str) {
    330         super.insert(offset, str);
    331         return this;
    332     }
    333
    334     /**
    335      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    336      */
    337     @Override
    338     public StringBuilder insert(int offset, char[] str) {
    339         super.insert(offset, str);
    340         return this;
    341     }
    342
    343     /**
    344      * @throws IndexOutOfBoundsException {@inheritDoc}
    345      */
    346     @Override
    347     public StringBuilder insert(int dstOffset, CharSequence s) {
    348             super.insert(dstOffset, s);
    349             return this;
    350     }
    351
    352     /**
    353      * @throws IndexOutOfBoundsException {@inheritDoc}
    354      */
    355     @Override
    356     public StringBuilder insert(int dstOffset, CharSequence s,
    357                                 int start, int end)
    358     {
    359         super.insert(dstOffset, s, start, end);
    360         return this;
    361     }
    362
    363     /**
    364      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    365      */
    366     @Override
    367     public StringBuilder insert(int offset, boolean b) {
    368         super.insert(offset, b);
    369         return this;
    370     }
    371
    372     /**
    373      * @throws IndexOutOfBoundsException {@inheritDoc}
    374      */
    375     @Override
    376     public StringBuilder insert(int offset, char c) {
    377         super.insert(offset, c);
    378         return this;
    379     }
    380
    381     /**
    382      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    383      */
    384     @Override
    385     public StringBuilder insert(int offset, int i) {
    386         super.insert(offset, i);
    387         return this;
    388     }
    389
    390     /**
    391      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    392      */
    393     @Override
    394     public StringBuilder insert(int offset, long l) {
    395         super.insert(offset, l);
    396         return this;
    397     }
    398
    399     /**
    400      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    401      */
    402     @Override
    403     public StringBuilder insert(int offset, float f) {
    404         super.insert(offset, f);
    405         return this;
    406     }
    407
    408     /**
    409      * @throws StringIndexOutOfBoundsException {@inheritDoc}
    410      */
    411     @Override
    412     public StringBuilder insert(int offset, double d) {
    413         super.insert(offset, d);
    414         return this;
    415     }
    416
    417     @Override
    418     public int indexOf(String str) {
    419         return super.indexOf(str);
    420     }
    421
    422     @Override
    423     public int indexOf(String str, int fromIndex) {
    424         return super.indexOf(str, fromIndex);
    425     }
    426
    427     @Override
    428     public int lastIndexOf(String str) {
    429         return super.lastIndexOf(str);
    430     }
    431
    432     @Override
    433     public int lastIndexOf(String str, int fromIndex) {
    434         return super.lastIndexOf(str, fromIndex);
    435     }
    436
    437     @Override
    438     public StringBuilder reverse() {
    439         super.reverse();
    440         return this;
    441     }
    442
    443     @Override
    444     @HotSpotIntrinsicCandidate
    445     public String toString() {
    446         // Create a copy, don't share the array
    447         return isLatin1() ? StringLatin1.newString(value, 0, count)
    448                           : StringUTF16.newString(value, 0, count);
    449     }
    450
    451     /**
    452      * Save the state of the {@code StringBuilder} instance to a stream
    453      * (that is, serialize it).
    454      *
    455      * @serialData the number of characters currently stored in the string
    456      *             builder ({@code int}), followed by the characters in the
    457      *             string builder ({@code char[]}).   The length of the
    458      *             {@code char} array may be greater than the number of
    459      *             characters currently stored in the string builder, in which
    460      *             case extra characters are ignored.
    461      */
    462     @java.io.Serial
    463     private void writeObject(java.io.ObjectOutputStream s)
    464         throws java.io.IOException {
    465         s.defaultWriteObject();
    466         s.writeInt(count);
    467         char[] val = new char[capacity()];
    468         if (isLatin1()) {
    469             StringLatin1.getChars(value, 0, count, val, 0);
    470         } else {
    471             StringUTF16.getChars(value, 0, count, val, 0);
    472         }
    473         s.writeObject(val);
    474     }
    475
    476     /**
    477      * readObject is called to restore the state of the StringBuffer from
    478      * a stream.
    479      */
    480     @java.io.Serial
    481     private void readObject(java.io.ObjectInputStream s)
    482         throws java.io.IOException, ClassNotFoundException {
    483         s.defaultReadObject();
    484         count = s.readInt();
    485         char[] val = (char[]) s.readObject();
    486         initBytes(val, 0, val.length);
    487     }
    488
    489 }