String
1. Definition: immutable character sequence
- The String class is modified by the final keyword, which means that the String class cannot be inherited, and its member methods default to the final method;
- Once a string is created, it cannot be modified
- JDK 8, the value of the string instance is stored through the character array char[] value.
- JDK 9, string uses byte[] value internally to store data
- When you re assign a string, connect concat, or replace, you need to re-establish the memory area. You cannot use the original value space for assignment.
- When a literal value is assigned to a string (different from new), the string value is declared in the string constant pool.
2. Common methods
Judgment method
method | explain |
---|---|
boolean equals(Object obj) | Compare whether the string contents are the same, case sensitive |
boolean equalsIgnoreCase(String str) | Compare whether the contents of the string are the same, ignoring case |
boolean contains(String str) | Determine whether a large string contains a small string |
boolean startsWith(String str) | The judgment string starts with a specified string |
boolean endsWith(String str) | The judgment string ends with a specified string |
int compareTo(Object o) | Compare this string with another object. |
int compareTo(String anotherString) | Compares two strings in dictionary order. |
int compareToIgnoreCase(String str) | Compares two strings in dictionary order, regardless of case. |
boolean contentEquals(StringBuffer sb) | Returns true if and only if the string has characters in the same order as the specified StringBuffer. |
boolean matches(String regex) | Tells whether this string matches the given regular expression. |
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) | Tests whether two string regions are equal. |
obtain
public int indexOf(int ch) | Gets the index of the first occurrence of the specified character in this string. | |
---|---|---|
public int indexOf(int ch, int fromIndex) | Gets the index of the first occurrence of the specified character in this string. | |
public int indexOf(String str) | Returns the index of the specified string at the first occurrence in this string | |
public int indexOf(String str, int fromIndex) | Returns the index of the specified string at the first occurrence after the specified position in the string | |
int lastIndexOf(int ch) | Returns the index of the last occurrence of the specified character in this string. | |
int lastIndexOf(int ch, int fromIndex) | Returns the index of the last occurrence of the specified character in this string, starting with the specified index. | |
int lastIndexOf(String str) | Returns the index of the rightmost occurrence of the specified substring in this string. | |
int lastIndexOf(String str, int fromIndex) | Returns the index of the last occurrence of the specified substring in this string, and searches backwards from the specified index. | |
char charAt(int index) | Returns the char value at the specified index. | |
public String substring(int start) | Returns a new string to get the substring | |
public String substring(int start, int end) | Returns a new string to get the substring | |
CharSequence subSequence(int beginIndex, int endIndex) | Returns a new character sequence, which is a subsequence of this sequence. | |
String concat(String str) | Concatenates the specified string to the end of this string. |
byte[] getBytes() | Encode this String as a byte sequence using the platform's default character set, and store the result in a new byte array. | |
---|---|---|
byte[] getBytes(String charsetName) | Encodes this String into a byte sequence using the specified character set, and stores the result in a new byte array. | |
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) | Copy characters from this string to the target character array. | |
int hashCode() | Returns the hash code of this string. | |
String intern() | Returns a normalized representation of a string object. |
int length() | Returns the length of this string. | |
---|---|---|
String replace(char oldChar, char newChar) | Returns a new string obtained by replacing all oldchars that appear in this string with newChar. | |
String replaceAll(String regex, String replacement ) | Replace all substrings of this string that match the given regular expression with the given replacement. |
String replaceFirst(String regex, String replacement) | Replace this string with the given replacement to match the first substring of the given regular expression. | |
---|---|---|
String[] split(String regex) | Splits the string based on the match of the given regular expression. | |
String[] split(String regex, int limit) | Splits the string based on matching the given regular expression. | |
static String valueOf(primitive data type x) | Returns the string representation of the x parameter of the given data type. | |
char[] toCharArray() | Converts this string to a new character array. | |
static String copyValueOf(char[] data) | Returns a String representing the character sequence in the specified array. | |
static String copyValueOf(char[] data, int offset, int count) | Returns a String representing the character sequence in the specified array. | |
String toLowerCase() | Convert all characters in this String to lowercase using the rules of the default locale. | |
String toLowerCase(Locale locale) | Converts all characters in this String to lowercase using the rules of the given Locale. | |
String toString() | Returns the object itself (it is already a string!). | |
String toUpperCase() | Convert all characters in this String to uppercase using the rules of the default locale. | |
String toUpperCase(Locale locale) | Convert all characters in this String to uppercase using the rules of the given Locale. | |
String trim() | Returns a copy of a string, ignoring leading and trailing whitespace. |
String type conversion
- Conversion between String and int
//String to int int i = new Integer(s).intValue() int i = Integer.parseInt(String s); //int to String String s = i + ""; String s = new Integer(i).toString; String s = String.valueOf(i); //The following two are equivalent s = i + "" s = String.valueOf(i); //The following two are also equivalent s = "abc" + i; s = new StringBuilder("abc").append(i).toString();
- You can convert other base types to string types through construction methods
String memory model
1. The difference between string s = "abc" and new String()
String s1 = new String("hello"), actually two objects will be created. First, a space storage string is created in the heap space. Secondly, a space storage string constant value is created in the constant pool. Finally, s1 reference the address of the heap space.
String s2 = "abc", find out whether the constant value already exists in the constant pool. If it does not exist, open space directly in the constant pool, and s2 refers to the address in the constant pool.
2. intern() method
Understand the function of the intern method: if a string calls the intern method, the JVM will look for the string in the string constant pool,
If it exists, it directly returns the reference of the corresponding Strnig in the constant pool;
If it does not exist, an equivalent String will be created in the constant pool, and then the reference of this String in the constant pool will be returned. Therefore, as long as it is an equivalent String object, the same String reference in the constant pool will be returned by using the intern() method,
JDK 7 moves the constant pool from the permanent generation area to the heap area. During the intern operation, if the string already exists in the constant pool, the string reference will be returned directly. Otherwise, the heap space of the string object will be copied into the constant pool and returned. Thus, the same reference is used in the heap and constant pool.
Look at the use of intern
String s1 = "hello"; String s2 = new String("hello"); System.out.println(s1 == s2);//JDK 8 :false
String s1 = "hello"; String s2 = new String("hello").intern(); System.out.println(s1 == s2);//JDK 8 :true
3. The new string process will create several objects
* reflection: * new String("ab")How many objects will be created? A: look at the bytecode, you know it's two. * One object is: new Keywords created in heap space * Another object is the object in the string constant pool"ab". Bytecode instruction: ldc * reflection: * new String("a") + new String("b")How many objects will the process create? Answer: six * Object 1: new StringBuilder() * Object 2: new String("a") * Object 3: in constant pool"a" * Object 4: new String("b") * Object 5: in constant pool"b" * * In depth analysis: StringBuilder of toString(), No one was created String object * Object 6: new String("ab") * Emphasize that by looking at bytecode, StringBuilder of toString()In the string constant pool, there is no generate"ab" * How to guarantee variables s Is it pointing to the data in the string constant pool? * There are two ways: * Mode 1: String s = "shkstart";//How literal quantities are defined * Method 2: call intern() * String s = new String("shkstart").intern(); * String s = new StringBuilder("shkstart").toString().intern();
A common misjudgment
String s3 = new String("1") + new String("1");//Point to heap space String s4 = "11";//Point to constant pool String s5 = "11";//Point to constant pool System.out.println(s3 == s4);//false System.out.println(s3.equals(s4));//true, overridden System.out.println(s5 == s4);//true
4. Addition rules between strings
Variables are added first to open space and then spliced, constants are spliced first and then found, and if not, they are created
- The splicing results of constants and constants are in the constant pool. The principle is compiler optimization
- Constants with the same content will not exist in the constant pool (the principle is HashTable)
- If there is a variable during splicing, the compiler cannot optimize, and the runtime can know the value of the variable. Therefore, the splicing results are stored in heap memory. The principle is to use StringBuilder
- If the splicing result is finally called intern(), the active pool is actively retrieved. Only when the result is not present in the constant pool, then the result is optimized to the constant pool. After optimization, the reference in the constant pool is equal to the reference in the heap memory.
Illustration of call form:
Note: it can be seen that when the + connector is widely used, the efficiency will be reduced due to the creation of multiple StringBuilder instances.
public class StringTest5 { @Test public void test1(){ String s1 = "a" + "b" + "c";//Compile time optimization: equivalent to "abc" String s2 = "abc"; //"abc" must be placed in the string constant pool and assigned this address to s2 /* * final. java compiled into Class, and then execute class * String s1 = "abc"; * String s2 = "abc" */ System.out.println(s1 == s2); //true System.out.println(s1.equals(s2)); //true }
@Test public void test2(){ String s1 = "javaEE"; String s2 = "hadoop"; String s3 = "javaEEhadoop"; String s4 = "javaEE" + "hadoop";//Compile time optimization //If there are variables before and after the splicing symbol, it is equivalent to new String() in the heap space. The specific content is the spliced knot Results: javaEEhadoop String s5 = s1 + "hadoop"; String s6 = "javaEE" + s2; String s7 = s1 + s2; System.out.println(s3 == s4);//true System.out.println(s3 == s5);//false System.out.println(s3 == s6);//false System.out.println(s3 == s7);//false System.out.println(s5 == s6);//false System.out.println(s5 == s7);//false System.out.println(s6 == s7);//false //intern(): judge whether there is a javaEEhadoop value in the string constant pool. If so, it will be returned to the constant pool javaEEhadoop Address of the; //If javaEEhadoop does not exist in the string constant pool, a copy of javaEEhadoop is loaded in the constant pool and returned The address of the secondary object. String s8 = s6.intern(); System.out.println(s3 == s8);//true }
/* s4 = s1 + s2 as follows; Execution details of: (variable s is temporarily defined by me) ① StringBuilder s = new StringBuilder(); ② s.append("a") ③ s.append("b") ④ s.toString() --> Approximately equal to new String("ab") Add: in jdk5 After 0, StringBuilder is used in jdk5 StringBuffer was used before 0 */ @Test public void test3(){ String s1 = "a"; String s2 = "b"; String s3 = "ab"; String s4 = s1 + s2;//Left and right are variables System.out.println(s3 == s4);//false }
Remember that final and static are also optimized by the compiler?
/* 1. String splicing does not necessarily use StringBuilder! If the left and right sides of the splice symbol are string constants or constant references, compile time optimization, that is, non StringBuilder, is still used. 2. final,static Will be optimized by the compiler. It is recommended to use final when it can be used for structures that modify classes, methods, basic data types and reference data types. Compile time optimization means that in the prepare stage of the link, the variable has completed the default initialization and assignment operation, and there is already a value to the right of the equal sign */ @Test public void test4(){ final String s1 = "a"; final String s2 = "b"; String s3 = "ab"; String s4 = s1 + s2;//S1 and S2 are non variables modified with final System.out.println(s3 == s4);//true }