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