String source code analysis, string source code

Source: Internet
Author: User

String source code analysis, string source code

The String class maintains a char [] type value to store strings. The source code is relatively simpler.

1. Immutable

The immutability of String is mainly reflected in three aspects:

  • The String class is defined as the final type and cannot be inherited.
  • Value [] In String is defined as final
  • All operations to generate a new String in String are called Array. copy or System. copy at the underlying layer to generate a new String object.
2. constructor: String constructor is relatively simple, but the following are special
    public String(String original) {        this.value = original.value;        this.hash = original.hash;    }        String(char[] value, boolean share) {        // assert share : "unshared not supported";        this.value = value;    }

The above two are special constructors. The first one uses a ready-made String to initialize a New String object. The constructor directly points the value of the New String object to the old value object. Because String is immutable, you do not need to copy a value object again here. The second constructor seems to damage the non-variability of the String type (the String will also change when the parameter value changes), but the constructor is not explicitly public and can only be used in the package, the underlying String (char value []) declared as public calls Array. copy to copy the underlying data. We do not recommend that you use the above two constructors.

    public String(char value[], int offset, int count) {        if (offset < 0) {            throw new StringIndexOutOfBoundsException(offset);        }        if (count < 0) {            throw new StringIndexOutOfBoundsException(count);        }        // Note: offset or count might be near -1>>>1.        if (offset > value.length - count) {            throw new StringIndexOutOfBoundsException(offset + count);        }        this.value = Arrays.copyOfRange(value, offset, offset+count);    }

The preceding constructor is typical. Many other constructor functions are similar to this one or call this constructor at the underlying layer. The input parameter is a char array (byte []). offset and count offset. The underlying layer calls the Arrays. copy function for deep replication.

Public String (StringBuffer buffer) {synchronized (buffer) {// ensure thread security this. value = Arrays. copyOf (buffer. getValue (), buffer. length () ;}} public String (StringBuilder builder) {this. value = Arrays. copyOf (builder. getValue (), builder. length ());}

The input parameters of the two constructors are StringBuffer and StringBuilder respectively. The bottom layer calls Arrays. copyOf. The only difference is that StringBuffer is thread-safe, and the synchronized keyword is required for all calls.

3. Other Methods
    static int indexOf(char[] source, int sourceOffset, int sourceCount,            char[] target, int targetOffset, int targetCount,            int fromIndex) {        if (fromIndex >= sourceCount) {            return (targetCount == 0 ? sourceCount : -1);        }        if (fromIndex < 0) {            fromIndex = 0;        }        if (targetCount == 0) {            return fromIndex;        }        char first = target[targetOffset];        int max = sourceOffset + (sourceCount - targetCount);        for (int i = sourceOffset + fromIndex; i <= max; i++) {            /* Look for first character. */            if (source[i] != first) {                while (++i <= max && source[i] != first);            }            /* Found first character, now look at the rest of v2 */            if (i <= max) {                int j = i + 1;                int end = j + targetCount - 1;                for (int k = targetOffset + 1; j < end && source[j]                        == target[k]; j++, k++);                if (j == end) {                    /* Found whole string. */                    return i - sourceOffset;                }            }        }        return -1;    }        static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,            char[] target, int targetOffset, int targetCount,            int fromIndex) {        /*         * Check arguments; return immediately where possible. For         * consistency, don't check for null str.         */        int rightIndex = sourceCount - targetCount;        if (fromIndex < 0) {            return -1;        }        if (fromIndex > rightIndex) {            fromIndex = rightIndex;        }        /* Empty string always matches. */        if (targetCount == 0) {            return fromIndex;        }        int strLastIndex = targetOffset + targetCount - 1;        char strLastChar = target[strLastIndex];        int min = sourceOffset + targetCount - 1;        int i = min + fromIndex;        startSearchForLastChar:        while (true) {            while (i >= min && source[i] != strLastChar) {                i--;            }            if (i < min) {                return -1;            }            int j = i - 1;            int start = j - (targetCount - 1);            int k = strLastIndex - 1;            while (j > start) {                if (source[j--] != target[k--]) {                    i--;                    continue startSearchForLastChar;                }            }            return start - sourceOffset + 1;        }    }

IndexOf and lastIndexOf are mainly called at the underlying layer of the index and lastIndex functions. The read-through code will find that the underlying implementation does not have a particularly awesome kmp algorithm, and it is still implemented by one character and one character scanning. LastIndexOf still uses the continue startSearchForLastChar, which is relatively rare.

Public String replace (char oldChar, char newChar) {if (oldChar! = NewChar) {int len = value. length; int I =-1; char [] val = value;/* avoid getfield opcode */while (++ I <len) {if (val [I] = oldChar) {break ;}// if not found, this if (I <len) is returned) {char buf [] = new char [len]; for (int j = 0; j <I; j ++) {buf [j] = val [j];} while (I <len) {char c = val [I]; // replace buf [I] = (c = oldChar )? NewChar: c; I ++;} // return a new String. Use the Non-public constructor in the preceding package to return new String (buf, true) ;}} return this ;}

Replace is used to replace one character in the String object with another character. If no specific character is found, the system returns itself. If it is found, a New String object is created and returned.

--- Restore content end ---

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.