JAVA -- API -- Object String StringBuffer/StringBuilder

Posted by mindfield on Mon, 20 Dec 2021 12:11:42 +0100

API introduction

  • API (Application Programming Interface) refers to some predefined interfaces (such as functions and HTTP interfaces), or conventions for the connection of different components of software system. It is used to provide a set of routines that application programs and developers can access based on certain software or hardware without accessing the source code or understanding the details of internal working mechanism.

Object

1. General

  • Object is the top-level parent class and the parent class of all Java classes. Each class uses object as a superclass. All objects (including arrays) implement the methods of this class, that is, inherit object by default
  • Exists in Java The lang.Object package does not need to be imported

2. Test

  • Test Object class
    package cn.tedu.api;
    
    import java.util.Objects;
    
    //This class is used to test the top-level parent class Object
    public class TestObject {
        public static void main(String[] args) {
            //4. Create objects for testing
            Student s = new Student("Zhang San",18);
            Student s2 = new Student();
            Student s3 = new Student("Zhang San", 18);
            /* Test toString() */
            //5. Print the attribute value of the object
            /* Before rewriting the toString() method, the address value is printed. After rewriting, the type and attribute value of the object are printed */
            System.out.println(s);
            System.out.println(s2);
    
            //6. Test hashCode()
            /**
             * Returns the hash code value of the object, which is used to distinguish different objects. Different objects generate different hash code values
             */
            System.out.println(s.hashCode());
            System.out.println(s2.hashCode());
            System.out.println(s3.hashCode());
            System.out.println(s == s3);
            /* Test equals() */
            /**
             * Object The underlying equals is also = = compared with the address value
             * So when printing false at the beginning, compare the objects of reference types s and s3
             * To override the equals and hashCode methods
             */
            System.out.println(s.equals(s3));
    
        }
    }
    //1. Create a student class for testing
    class Student{
        //2. Define attributes
        String name;
        int age;
    
    
        //3.1 generate non parametric and full parametric structures
        public Student() {
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        //5.1 rewrite toString()
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        //7.2 adding rewritten equals()
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Student)) return false;
            Student student = (Student) o;
            return age == student.age &&
                    Objects.equals(name, student.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
    }
    
    

3. Method extract

  • boolean | equals(Object obj): the equals method provided by Object. By default, = = comparison is used, and the address value is compared. If you want to compare specific content, override the equals method (usually also override the hashCode) method
    • Source code excerpt
      public boolean equals(Object obj) {
              return (this == obj);
          }
      
  • int | hashCode(): returns the hash code value of the object
  • String | toString(): returns the address value of the object (before rewriting, the default address value is printed; after rewriting, the object type and attribute value are printed)

String

4. General

  • String encapsulates a char [] array at the bottom
  • String is an immutable string and a constant
    • Source code excerpt
      public final class String
      private final char value[];
      

5. How to create objects

package cn.tedu.api;

//This class is used to practice the creation and common methods of String
public class TestString {
    public static void main(String[] args) {
        //1. Practice creating a String
        /**
         * The bottom layer of string maintains char [], which is stored in heap memory
         */
        char[] value = {'a','b','c'};
        //Trigger a parameterized construct to create a String class object
        String s1 = new String(value);
        String s11 = new String(value);

        //2. Practice the second method of creating String
        /**
         * When created in this way, the bottom layer will also store new String() in the constant pool in heap memory, which is efficient
         */
        String s2 = "abc";
        String s22 = "abc";

        //3. Test
        /**
         * The second method is to define a String object directly and store the object in the constant pool. If the values are the same, it will not be created
         * Instead, the value is re assigned to another object, so if the two String values are the same, it is true during comparison
         * == The address values of the two objects are compared
         * Object The default implementation of equals() in the class is also = = comparison, which compares the address value
         * In the String class, equals() is overridden. Instead of comparing address values, the specific contents of two strings are compared
         * That is, true is returned as long as the two values are the same
         */
        System.out.println(s1 == s2); //false
        System.out.println(s1 == s11); //false
        System.out.println(s2 == s22); //true
        System.out.println(s1.equals(s11)); //true
        System.out.println(s1.equals(s2)); //true
    }
}

  • Summary:
    • The first way to create objects
      • Stored in heap memory, a new String object is allocated each time
      • The address value is different every time
    • The second way to create objects
      • Simple and efficient, stored in the constant pool of heap memory
      • If a string is used for the first time, an object is created in the heap constant pool
      • If the two assignments are the same, the new object is no longer created, but the value is reassigned to another object

6. Common test methods

package cn.tedu.api;

import java.util.Arrays;

//This class is used to practice the common methods of the String class
public class TestString2 {
    public static void main(String[] args) {
        //1. Create string
        String s = "abc";

        char [] value = {'a','b','c'};
        String ss = new String(value);

        //2. Common test methods
        /* charAt  Gets the character at the specified subscript*/
        System.out.println(s.charAt(1));

        /* concat  It is used to splice the specified string. Note that the original string will not be changed, but a new string will be created for storage*/
        String s2 = s.concat("cxy");
        System.out.println(s); //abc
        System.out.println(s2); //abccxy

        /*  */
        System.out.println(s.concat("cxy")); //abccxy
        System.out.println(s.endsWith("y")); //false
        System.out.println(s.startsWith("a")); //true

        System.out.println(s == ss); //false
        System.out.println(s.equals(ss)); //true

        //Gets the subscript value of the first occurrence of the specified element
        System.out.println(ss.indexOf("b")); //1
        ss = "abcbb";
        //Gets the subscript value of the last occurrence of the specified element
        System.out.println(ss.lastIndexOf("b")); //4

        //Get the length of the specified string (unlike the array, the array does not have (), the array is an attribute, and this is a method)
        System.out.println(ss.length()); //5

        String s3 = "a b c d e";
        // split splits a String according to the specified rules. The main return value type is String []
        // Arrays. Is required ToString array tool class method to print
        System.out.println(s3.split(" "));
        System.out.println(Arrays.toString(s3.split(" ")));

        // Substring intercepts the substring from the specified location. If there is only one subscript, it intercepts from the specified location, including the specified location
        // If there are two subscripts, intercept the part between the two subscripts, close left and open right
        System.out.println(s3.substring(3)); // c d e------[3, end]
        System.out.println(s3.substring(1, 5)); // b c-----[1,5)

        //Convert to all uppercase and all lowercase
        System.out.println(s3.toUpperCase()); //A B C D E
        System.out.println(s3.toLowerCase()); //a b c d e

        s3 = "    abcde    ";
        //Returns a copy, removing leading and trailing spaces
        System.out.println(s3.trim()); //abcde

        // Convert other types of values to String
        System.out.println("20"+10); //2010
        System.out.println(String.valueOf(10)); //10
        System.out.println(String.valueOf(80)+10); //8010
        System.out.println(10+10); //20


    }
}

7. Extract of common methods

  • char | charAt(int index): gets the character at the specified subscript
  • Int | CompareTo (string otherstring): compares two strings in dictionary order (the comparison is based on the Unicode value of each character in the string.)
  • String | concat(String str): used to splice strings at the end (note that the original string will not be changed, but a new string will be returned)
  • Boolean | contains (charsequences): returns true if and only if the string contains the specified character
  • boolean | endsWith(String suffix): check whether the string ends with the specified string
  • boolean | equals(Object anObject): check whether the current string is equal to the specified string (string overrides equals() by default, comparing the contents of the two strings, and returns true if they are equal)
  • byte[] | getBytes(Charset charset): converts the current string using the specified character encoding and stores it in a new byte array
  • int | hashCode(): returns a hash code value
  • int | indexOf(String str): returns the subscript value of the first occurrence of the specified element
  • boolean | isEmpty(): check whether the current string is empty
  • int | lastIndexOf(String str): gets the subscript value of the last occurrence of the specified element
  • int | length(): get the length of the specified string (note that this is the length() method and the array is the length attribute)
  • String | replace(char oldChar, char newChar): replaces the specified character
  • String[] | split(String regex): splits a string according to the specified rules, and the return value type is string [] (this method requires Arrays.toString() array tool class to print)
  • boolean | startsWith(String prefix): check whether the string starts with the specified string
  • String | substring(int beginIndex): intercept the substring from the specified position. If there is only one subscript, intercept it from the subscript position to the last ([subscript, end]); if there are two subscripts, intercept the direct part of the two subscripts, close left and open right ([subscript, another subscript - 1])
  • char[] | toCharArray(): converts the current string into a character array
  • String | toLowerCase(): convert all to lowercase
  • String | toString(): returns a string
  • String | toUpperCase(): convert all to uppercase
  • String | trim(): returns a copy, removing the first space
  • static | String valueOf(Object obj): convert other types of data to String type, or directly splice a ""

8. Comparison of = = and equals()

  • ==: when both are numerical types, the specific values of the two are compared; When both are reference types, the address value (physical address / memory address) is compared
  • equals(): the address value in the object is still compared. After rewriting, the specific attribute value is compared
  • equals() in the String source code overrides equals() by default in String
	/**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            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;
    }

StringBuffer/StringBuilder

9. General

  • Both are variable length strings
  • The bottom layer encapsulates a char [], with an initial capacity of 16
  • You can splice strings using the append method
  • StringBuffer is thread safe and StringBuilder is more efficient

10. Test

package cn.tedu.api;

//This class is used to practice string splicing
public class TestString3 {
    public static void main(String[] args) {
        //method(); // Normal string splicing
        method2(); //Efficient string splicing
    }
    //Normal string splicing
    private static void method() {
        //Requirements: splicing and printing 26 lower case letters 10000 times
        //1. Save 26 letters in the definition string
        String str = "abcdefghijklmnopqrstuvwxyz";
        //2. Splice the specified string 10000 times
        //2.1 first define a variable to save the result
        String result = "";
        //We can add a timing function to the program
        //4.1 obtain the current time of the system as the start time before the cycle
        long t1 = System.currentTimeMillis();
        //2.2 splice after 10000 cycles
        for (int i=1;i<=10000;i++){
            result += str;
        }
        //4.2 after the cycle ends, obtain the current time of the system as the end time
        long t2 = System.currentTimeMillis();
        //3. Print the splicing results
        System.out.println("The result of splicing is"+result);
        //4.3 printing consumption time: end time - start time = consumption time
        System.out.println("Time spent is"+(t2 - t1));


    }
    //Efficient string splicing
    private static void method2() {
        //1. Save 26 letters in the definition string
        String str = "abcdefghijklmnopqrstuvwxyz";

        //2. Optimization: String - > StringBuilder / StringBuffer
        //StringBuilder is faster, thread unsafe, and single thread operates strings
        //StringBuffer, thread safe, multithreaded operation string
        StringBuilder sb = new StringBuilder();
        StringBuffer sb2 = new StringBuffer();
        //2. Splice the specified string 10000 times
        //2.1 first define a variable to save the result
//        String result = "";
        //We can add a timing function to the program
        //4.1 obtain the current time of the system as the start time before the cycle
        long t1 = System.currentTimeMillis();
        System.out.println(t1);
        //2.2 splice after 10000 cycles
        for (int i=1;i<=10000;i++){
            //Optimized to splice using append
            //sb.append(str);
            sb2.append(str);
        }
        //4.2 after the cycle ends, obtain the current time of the system as the end time
        long t2 = System.currentTimeMillis();
        System.out.println(t2);
        //3. Print the splicing results
        System.out.println("The result of splicing is"+sb2);
        //4.3 printing consumption time: end time - start time = consumption time
        System.out.println("Time spent is"+(t2 - t1));
    }
}

11. Comparison of string / StringBuffer / StringBuilder

  • String: immutable long string
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
    private final char value[];
/**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }    
  • StringBuffer: thread safe
	@Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }
  • StringBuilder: thread unsafe, but more efficient
	@Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }
  • What are the classes of operation strings in Java? What's the difference between them?
    • String,StringBuffer,StringBuilder. The difference is that string declares immutable objects, and each operation must produce a new object; Both StringBuffer and StringBuilder inherit from the abstract class AbstractStringBuilder; StringBuffer is added with synchronization keyword, which has thread safety;
    • In usage scenarios, StringBuffer is required for concurrency, StringBuilder is required for iteration, and String is required for ordinary scenarios to avoid unnecessary type conversion overhead in the middle.

12. Capacity expansion mechanism

  • The initial capacity is 16
    	/**
         * Constructs a string buffer with no characters in it and an
         * initial capacity of 16 characters.
         */
        public StringBuffer() {
            super(16);
        }
    
  • Capacity expansion mechanism
	/**
     * Ensures that the capacity is at least equal to the specified minimum.
     * If the current capacity is less than the argument, then a new internal
     * array is allocated with greater capacity. The new capacity is the
     * larger of:
     * <ul>
     * <li>The {@code minimumCapacity} argument.
     * <li>Twice the old capacity, plus {@code 2}.
     * </ul>
     * If the {@code minimumCapacity} argument is nonpositive, this
     * method takes no action and simply returns.
     * Note that subsequent operations on this object can reduce the
     * actual capacity below that requested here.
     *
     * @param   minimumCapacity   the minimum desired capacity.
     */
    public void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > 0)
            ensureCapacityInternal(minimumCapacity);
    }

    /**
     * This method has the same contract as ensureCapacity, but is
     * never synchronized.
     */
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
    }
	/**
     * This implements the expansion semantics of ensureCapacity with no
     * size check or synchronization.
     */
    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }
  • If the character length after splicing is < = the initial capacity, the capacity remains unchanged and is still 16
  • After the character len gt h after splicing is > = the initial capacity, start the capacity expansion, and the capacity will be expanded once according to the current (initial) capacity * 2 + 2
    • Why + 2
  • When one additional expansion is not enough even if it is expanded according to n * 2 + 2, its capacity will be directly expanded to a length equal to the length of the added string. That is, when k > 2n + 2, the capacity becomes K. It will be added later, and the capacity will be expanded according to the current capacity * 2 + 2

Topics: Java string object