String

String is a very common class

Source code analysis

// This value is used for character storage
private final char value[];

// Cache the hash code of the string
private int hash;// Default to 0

// This is a constructor
// Pass in the string object value as the array value,
// Assign to the current object being constructed, and hash works the same way.

public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
}



// There are many ways to initialize a String
// Empty parameter initialization
/ / the String to initialize
// Initialize the character array
// Initialize the byte array
// Construct StringBuffer, StringBuilder


Copy the code

Question: I am preparing to construct a String object, so where does the original object come from? When was it constructed?

Test it out:

public static void main(String[] args) {
        String str = new String("zwt");
        String str1 =  new String("zwt");
}
Copy the code

In Java, when a value is enclosed by double quotes (as in this example, “ABC “), the JVM first checks to see if the ABC object is in the constant pool,

If not, initialize ABC as an object into the constant pool. If so, return the constant pool contents directly.

Java strings are declared differently in heap memory.

To avoid duplicate object creation, use String s1 =”123″ instead of String s1 = new String(“123”) because the JVM is optimized for the former.

The commonly used API

System.out.println(str.isEmpty());// Check if it is an empty string
System.out.println(str.length());// Get the length of the string
System.out.println(str.charAt(1));// Gets the character at the specified position
System.out.println(str.substring(2.3));// Intercepts the specified interval string
System.out.println(str.equals(str1));// Compare strings
Copy the code

isEmpty()

    public boolean isEmpty(a) {
        return value.length == 0;
    }
Copy the code

length()

    public int length(a) {
        return value.length;
    }
Copy the code

charAt()

    public char charAt(int index) {
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
    }
Copy the code

substring()

    public String substring(int beginIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        int subLen = value.length - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        // Return the current object if the start range is exactly 0 and the end range is equal to the length of the array.
        Otherwise, rebuild the String with the array and the start and end ranges passed in and return.
        return (beginIndex == 0)?this : new String(value, beginIndex, subLen);
    }
Copy the code

equals()

    public boolean equals(Object anObject) {
        // If it is the same reference, return true
        if (this == anObject) {
            return true;
        }
        // Check if it is a String
        if (anObject instanceof String) {
            // Check whether the length is consistent
            String anotherString = (String)anObject;
            int n = value.length;
            // check whether each value in char[] is equal
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while(n-- ! =0) {
                    if(v1[i] ! = v2[i])return false;
                    i++;
                }
                return true; }}return false;
    }
Copy the code

The equals () and “= =”

There is no necessary connection between the two,

In reference types, “==” compares whether two references refer to the same address (the same object) in heap memory,

Equals is a normal method that returns results that depend on its implementation.

intern()

public native String intern(a);

// If the constant pool has the value of the current String, it returns that value, if it does not, it returns a reference to that value,
Copy the code

Some basic

Java base data types and reference types

There are four classes of eight basic data types in Java, and when you take away the four classes of eight basic data types, everything else is an object, or reference type.

Basic data types
Floating point types float double
character char
The logical model boolean
The integer byte short int long

Java automatic boxing/unboxing

If you add valueOf () to an Integer, then you add valueOf () to an Integer.

In JDK1.5, wrapper classes were added to the four basic types.

The first type: integerbyte Byte
short Short
int Integer
longThe second type of Long is floating pointfloat Float
doubleDouble Type 3: Logical typebooleanBoolean Class 4: characterschar Character
Copy the code

Converting an int variable into an Integer object is a process called boxing,

Converting an Integer object to a value of type int is called unboxing.

These methods of packing and unpacking are automatically added when the class file is compiled, without manual programmer intervention, so they are also called automatic packing/unpacking.

Use:

1. Objects are simulations of the real world.

2. Support for generics.

3. Provides rich properties and apis

public static void main(String[] args) {
        int int1 = 180;
        Integer int2 = new Integer(180);
}
Copy the code

The performance is shown as follows:

StringBuilder

The StringBuilder class is decorated with final and therefore cannot be inherited.

The StringBuilder class inherits from the AbstractStringBuilder class.

In fact, the AbstractStringBuilder class implements a set of operations on mutable character sequences,

For example, append(), INSERT (), delete(), replace(), charAt(), etc.

It’s worth noting that StringBuffers also inherit from the AbstractStringBuilder class.

The StringBuilder class implements two interfaces:

Serializable interface, which indicates that objects can be serialized.

The CharSequence interface provides several methods for read-only access to character sequences.

For example, the length(), charAt(), subSequence(), toString() methods, etc.

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable.CharSequence
Copy the code

Defined constant

// The cache of the last value returned by toString. Cleared whenever StringBuffer is modified.
private transient char[] toStringCache;
Copy the code

AbstractStringBuilder

abstract class AbstractStringBuilder implements Appendable.CharSequence {
    /** * The value is used for character storage. */
    //value is used to store characters in a character sequence. Value is a dynamic array that can be expanded when the storage capacity is insufficient.
    char[] value;

    /** * The count is the number of characters used. */
    //count represents the number of characters stored in the value array.
    int count;
    
    

Copy the code

A constructor

public StringBuilder(a) {
    super(16);
}

public StringBuilder(int capacity) {
    super(capacity);
}

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

public StringBuilder(CharSequence seq) {
    this(seq.length() + 16);
    append(seq);
}

// AbstractStringBuilder.java
AbstractStringBuilder(int capacity) {
    value = new char[capacity];
}

Copy the code

The StringBuilder class provides four constructors. The constructor basically does the initialization of the value array.

Among them:

  1. The default constructor sets the initial size of the value array to 16.
  2. The second constructor sets the initial size of the value array to the specified size.
  3. The third constructor takes a String as an argument, sets the initial size of the value array to the String length +16, and adds characters from the String to the value array.
  4. The fourth constructor takes a CharSequence object as an argument, sets the initial size of the value array to the length of the CharSequence object +16, and adds characters from the CharSequence object to the value array.

Append () method

There are several implementations, in general order:

Append () —-> ensureCapacityInternal() ensures that the value array has sufficient capacity —-> newCapacity() the newCapacity

    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) { value = Arrays.copyOf(value, newCapacity(minimumCapacity)); }}private int newCapacity(int minCapacity) {
        // overflow-conscious code
        
        // Capacity expansion parameters
        
        int newCapacity = (value.length << 1) + 2;
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)? hugeCapacity(minCapacity) : newCapacity; }Copy the code

In the code above, you can see that the specific expansion rule is * 2 + 2

StringBuffer

Basically a Synchronized StringBuilder.

What scenarios do StringBuilder and StringBuffer apply to?

Stringbuffer is thread-safe, stringBuffer is slower than StringBuilder, and in theory you should use thread-safe StringBuffer in the case of multiple threads.

There’s virtually no place to show that you need a thread-safe string splicer.

Stringbuffer has almost no applicable scenarios, and you should choose to use StringBuiler in all cases unless you have a scenario that requires thread-safety.

If you meet…

The thread-safe nature of a StringBuffer simply ensures that the JVM executes smoothly without throwing exceptions. It does not guarantee that the logic is correct and that calls are called in the correct order. Most of the time, what we need is not just thread safety, but locks.

Finally, why does stringBuffer exist at all, and if it really isn’t valuable, why does the JDK provide it?

The answer is too simple, because StringBuilder didn’t exist in the first place, and for whatever reason the Sun people decided to make StringBuffer thread-safe,

As a result, in jdk1.5, it was finally decided to provide a non-thread-safe implementation of stringbuffer and name it stringbuilder.

Incidentally, javac seems to have written all string operations with plus signs implicitly as StringBuilder from this version,

That said, from jdk1.5 onwards, there is little performance penalty for concatenating strings with plus signs.

Expand your knowledge

Java9 improves the implementation of strings, including String, StringBuffer, and StringBuilder.

Before Java9, strings used the char[] array to hold characters, so each character of the string was 2 bytes long.

Java9 strings use a byte[] array with an encoding-Flag field to hold characters, so each character of the string is only 1 byte.

So Java9 strings are much more space-efficient, and the string functionality methods are not affected.

Refer to the link

zhuanlan.zhihu.com/p/28216267

Blog.csdn.net/u012317510/…

www.zhihu.com/question/20…