Java String Source Analysis

Source: Internet
Author: User
Tags comparable

Introduction

From a section of code:

public void Stringtest () {String a = "a" + "B" +1;    String B = "AB1"; System.out.println (A = = B);}

Let's guess what the results are. If your conclusion is true. Okay, here's another piece of code:

public void Stringtest () {String a = new String ("AB1");    String B = "AB1"; System.out.println (A = = B);}

How did it end? The correct answer is false.

Let's see how the compiler compiles the code

The first paragraph of code public void Stringtest () {String a = "AB1";    String B = "AB1"; System.out.println (A = = B);}    The second paragraph of Code public void Stringtest () {String A1 = new String ("AB1");    String B = "AB1"; SYSTEM.OUT.PRINTLN (A1 = = b);}

That is, the first piece of code after the compilation period optimization, because the compiler found that "a" + "B" +1 and "ab1" effect is the same, are non-variable composition. But why are their memory addresses the same? If you are interested in this, take a look at some of the important source code of the String class.


A String class

The String class is modified by final, that is, the string object is immutable, and the concurrent program is most like an immutable variable. The String class implements the serializable, Comparable<string>, and Charsequence interfaces.

The comparable interface has the CompareTo (String s) method, the Charsequence interface has length (), charAt (int index), and the subsequence (int start,int end) method.


Two string properties

The string class contains an immutable char array to hold the string, and a variable hash of type int to hold the computed hash value.

/** The value is used for character storage. */private Final char value[];/** Cache the hash code for the string */private int hash;  Default to 0/** use Serialversionuid from JDK 1.0.2 for interoperability */private static final long Serialversionuid = -6849794470754667710l;


Three string constructors
Constructors that do not contain parameters are generally useless because value is an immutable variable public string ()  {    this.value = new &NBSP;CHAR[0];} parameter is String type public string (string original)  {    this.value =  Original.value;    this.hash = original.hash;} The parameter is a char array, using the arrays class in the Java.utils package to copy public string (char value[])  {     This.value = arrays.copyof (value, value.length);} Starting with the offset position in the bytes array, byte length is encoded in charsetname format and copied to valuepublic string (byte bytes[], int  offset, int length, string charsetname)          throws UnsupportedEncodingException {    if  (charsetname ==  null)         throw new nullpointerexception (" CharsetName ");     checkbounds (bytes, offset, length);    &nbsP;this.value = stringcoding.decode (charsetname, bytes, offset, length);} Call Public string (byte bytes[], int offset, int length, string  CharsetName) constructor public string (byte bytes[], string charsetname)          throws unsupportedencodingexception {    this (Bytes,  0, bytes.length, charsetname);}


Common methods of three stringsBoolean equals (Object anobject)
Public boolean equals (object anobject)  {    //If you are referencing the same object, return to True      if  (This == anobject)  {         return true;    }    //If the data is not of type string, return False      if  (anobject instanceof string)  {         string anotherstring =  (String)  anObject;         int n = value.length;        //if the char array length is not equal, return false          if  (n == anotherstring.value.length)  {             char v1[] = value;             char v2[] =  anotherstring.value;            int i = 0;             //from backward to single character, if there are unequal, return false              while  (n-- != 0)  {                 if  (V1[i] != v2[i])                           return false;                 i++;            }             //Each character is equal, returns True              return true;        }     }  &nbSp; return false;} 

The Equals method is often used to determine whether two objects are actually equal in meaning, and the string object judges the rule:

    1. True if the memory address is the same.

    2. False if the object type is not of type string. Otherwise continue to judge.

    3. False if the object length is not equal. Otherwise continue to judge.

    4. From the forward, determine whether a single character of the char array value in the String class is equal or false. Returns true if it remains equal until the first number.

As you can see, it is very time-consuming to compare two extra-long strings.


int CompareTo (String anotherstring)
Public int compareto (string anotherstring)  {    //own object string length len1     int len1 = value.length;    //is compared to the length of the object string len2     int len2 = anotherstring.value.length;    //the minimum value of two string lengths Lim     int lim = math.min (LEN1,&NBSP;LEN2);    char  v1[] = value;    char v2[] = anotherstring.value;     int k = 0;    //starts from the first character of value to the minimum length of Lim, if the characters are not equal, Returns itself (the object is not equal to the character-the unequal character of the object being compared)     while  (K < lim)  {         char c1 = v1[k];         char c2 = v2[k];        if  (C1&NBSP;!=&NBSP;C2)  {            return c1 - c2;         }        k++;    }    // Returns (itself length-the length of the object being compared)     return len1 - len2 if all the preceding are equal;}

This method is very clever, starting from 0 to determine the size of the character. If two objects can compare the characters of the place is also equal, directly return to their own length minus the length of the comparison object, if the length of the two strings are equal, the return is 0, cleverly judged three cases.


int Hashcode ()
Public int hashcode ()  {    int h = hash;     //If the hash is not computed and the string is not empty, the hashcode calculation     if  (h == 0 &&  value.length > 0)  {        char val[]  = value;        //calculation Process          //s[0]*31^ (n-1)  + s[1]*31^ (n-2)  + ... + s[n-1]         for  (int i = 0; i < value.length; i++ )  {            h = 31 * h  + val[i];        }         //hash Assignment         hash = h;     }    reTurn h;} 

The string class overrides the Hashcode method, and the Hashcode method in object is a native call. The hash of the string class is calculated using a polynomial, and we can derive the same hash by a different string, so the hashcode of the two string objects is the same, not the same as two strings.


Boolean StartsWith (String prefix,int toffset)
Public boolean startswith (String prefix, int toffset)  {     char ta[] = value;    int to = toffset;     char pa[] = prefix.value;    int po = 0;     int pc = prefix.value.length;    // note: toffset  might be near -1>>>1.    //If the starting address is less than 0 or (start address + object length compared) is greater than the length of its own object , Return False     if  ((toffset < 0)  | |   (TOFFSET&NBSP;&GT;&NBSP;VALUE.LENGTH&NBSP;-&NBSP;PC)  {         return false;    }    //compare from the end of the comparison object      while  (--pc >= 0)  {        if  (ta[to ++] != pa[po++]) &NBSP;{&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&Nbsp;      return false;        }     }    return true;} Public boolean startswith (String prefix)  {    return startswith ( prefix, 0);} Public boolean endswith (String suffix)  {    return startswith ( Suffix, value.length - suffix.value.length);}

Both the start and end comparisons are more commonly used methods, such as determining whether a string is an HTTP protocol, or whether a file is a MP3 file, and can be compared using this method.


String concat (String str)
public string concat (string str) {int otherlen = Str.length ();    If the added string is empty, the object itself is returned if (Otherlen = = 0) {return this;    } int len = value.length;    Char buf[] = arrays.copyof (value, Len + Otherlen);    Str.getchars (buf, Len); return new String (buf, True);}

The Concat method is also one of the frequently used methods, which determines whether the added string is empty to determine if a new object is to be created.


String replace (char Oldchar,char Newchar)
Public string replace (Char oldchar, char newchar)  {    // Old and new values first compare     if  (Oldchar != newchar)  {         int len = value.length;        int  i = -1;        char[] val = value;  /* avoid getfield opcode */        // Find the location where the old value first appears         while  (++i < len)  {             if  (Val[i] == oldchar)  {                 break;             }         }        //from that position, until the end, replace the old value that appears with the new value         if  (i <  len)  {            char buf[]  = new char[len];            for  ( int j = 0; j < i; j++)  {                 buf[j] = val[j];             }             while  (I < len)  {                 char c = val[i];                 buf[i] =  (C == oldchar)  ?  newchar : c;                i++;             }             return new string (buf, true);         }    }    return this;}

This method also has flattering, such as the first to find out where the old values appear, thus saving a part of the comparison time. The Replace (String oldstr,string newstr) method is judged by a regular expression.


String Trim ()
Public string trim ()  {    int len = value.length;     int st = 0;    char[] val = value;     /* avoid getfield opcode */    //the position where the front segment of the string has no spaces     while  ((St < len)  &&  (val[st] <=  '   ')  {        st++;    }     //find the position where there is no space at the end of the string     while  ((St < len)  &&  ( val[len - 1] <=  '   ')  {        len--;     }    //if no spaces appear before or after, the string itself is returned     return  (St  > 0)  | |   (len < value.length)  ? substring (St, len)  : this;}

The Trim method also uses up to 6 of the flying


String Intern ()
Public native String intern ();

The Intern method is the native call, which is used to find the equivalent object in the constant pool in the method area through the Equals method, and if it is not found, open a space in the constant pool to hold the string and return the reference to that corresponding string. Otherwise, directly returns a reference to a string object already in the constant pool.

The second code in the introduction

String a = new string ("AB1");//change to string a = new string ("Ab1"). Intern ();

The result is true because the address pointed to by a is from a constant pool, and the string constants pointed to by B call this method by default, so both A and B point to the same address space.


int Hash32 ()
private transient int hash32 = 0;int Hash32 () {int h = hash32;       if (0 = = h) {//Harmless data race on hash32 here.       h = sun.misc.Hashing.murmur3_32 (hashing_seed, value, 0, value.length); Ensure result is not a zero to avoid recalcing h = (0! = h)?       H:1;    Hash32 = h; } return h;}

In JDK1.7, the hash-related set class, in the case of the string class as key, no longer uses the Hashcode-mode discrete data, but uses the Hash32 method. This method by default uses the system current time, String class address, System class address and so on as the factor computation obtains the hash seed, through the hash seed obtains the 32-bit int type value through the hash.


public int Length () {return value.length;} Public String toString () {return this;} public Boolean isEmpty () {return value.length = = 0;} public char charAt (int index) {if (Index < 0) | | (index >= value.length))    {throw new stringindexoutofboundsexception (index); } return Value[index];}

These are some simple and common methods.


Summarize

The string object is an immutable type, and a string method that returns a type of string returns each time a new string object, in addition to some specific conditions of some methods, returns itself.

Three ways to compare String objects:

= = Memory Comparison: Direct comparison of two reference points to the memory value, accurate and concise straightforward.

equals string Value comparison: Compares the object literals of two references for equality.

Hashcode string Numeric comparison: numeric string. Two references to the same hashcode, does not guarantee that the memory must be the same, does not guarantee that the literal value must be the same.




Java String Source Analysis

Related Article

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.