#1. Characteristics of string
##1.1 invariance
We often hear that the key of HashMap suggests using immutable classes, such as String. Immutability here means that once the class value is initialized, it can no longer be changed. If it is modified, it will be a new class. Let's write a demo to demonstrate it.
public class test { public static void main(String[] args){ String str="hello"; str=str+"world"; } }
Judging from the code, the value of s seems to have been modified, but judging from the debug log, in fact, the memory address of S has been repaired. That is to say, the seemingly simple assignment of S = "world" has actually pointed the reference of s to the new String. The debug screenshot shows that the memory address has been modified. The two screenshots are as follows, We can see that the address value marked in red has been modified.
Use the schematic diagram to represent the heap memory, as shown in the figure below.
We can see that the address of str has been changed. It is said that two strings have been generated. The official annotation of string class is Strings are constant; their values cannot be changed after they are created. String is a constant; Their values cannot be changed after creation.
The following is the relevant code of String. We can see the following code:
- String is modified by final, which indicates that the string class can never be inherited, that is, any operation method of string will not be inherited or overwritten, which can ensure the parent delegation mechanism and the security of the base class.
- The data stored in string is an array value of char. We found that value is also modified by final, that is, once value is assigned, the memory address can never be modified, and the permission of value is private, which can never be accessed externally. String does not open a method to assign value, so once value is generated, the memory address cannot be modified at all.
/** 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;
##1.2 equality judgment
The equality judgment logic is clearly written. If someone asks how to judge whether the two are equal, we can start from the underlying structure of the two. In this way, we can quickly think of a practical idea and method, just like the underlying data structure of String is an array of char. When judging equality, we can compare whether the characters in the char array are equal one by one.
(dig a hole here first. Ctrip asked similar questions)
public boolean equals(Object anObject) { //If the addresses are equal, return true directly if (this == anObject) { return true; } //If it is a String, make the following logical judgment if (anObject instanceof String) { //Convert object to String String anotherString = (String)anObject; //Gets the length of the current value int n = value.length; //First compare whether the lengths are equal. If the lengths are not equal, the two must not be equal if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; //The while loop compares each char one by one while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
The flow chart of equal logic is as follows. We can see that the whole process is still very clear.
##1.3 replacement operation
Replacement is also often used in daily work. There are three scenarios: replace to replace all characters, replaceAll to replace strings in batch, and replaceFirst.
A demo is written below to demonstrate three scenarios:
public static void main(String[] args) { String str = "hello word !!"; System.out.println("Before replacement :" + str); str = str.replace('l', 'd'); System.out.println("Replace all characters :" + str); str = str.replaceAll("d", "l"); System.out.println("Replace all :" + str); str = str.replaceFirst("l", ""); System.out.println("Replace first l :" + str); }
The output is:
One thing to note here is the difference between replace and replaceAll, not replace and replace all the differences.
Instead, replaceAll supports regular expressions, so the parameters will be parsed (both parameters are). For example, replaceAll("\d", ""), but replace will not. replace("\d", "") is the string replacing "\ d" and will not be parsed into regular expressions.
##1.4 intern method
String.intern() is a Native method, that is, the code that c and c + + interact with the underlying. Its role (in
JDK1.6 and 1.7 operate differently
)Yes:
If the runtime constant pool already contains a String equal to the content of this String object, the reference of this String in the constant pool will be returned directly;
If not, then
In jdk1 6, add the String object to the constant pool, and then return the reference of the String object (at this time, the referenced String is in the constant pool).
In jdk1 7, put a reference to the address of the String object in the heap and return the reference address (at this time, the referenced String is in the heap).
/** * Returns a canonical representation for the string object. * <p> * A pool of strings, initially empty, is maintained privately by the * class {@code String}. * <p> * When the intern method is invoked, if the pool already contains a * string equal to this {@code String} object as determined by * the {@link #equals(Object)} method, then the string from the pool is * returned. Otherwise, this {@code String} object is added to the * pool and a reference to this {@code String} object is returned. * <p> * It follows that for any two strings {@code s} and {@code t}, * {@code s.intern() == t.intern()} is {@code true} * if and only if {@code s.equals(t)} is {@code true}. * <p> * All literal strings and string-valued constant expressions are * interned. String literals are defined in section 3.10.5 of the * <cite>The Java™ Language Specification</cite>. * * @return a string that has the same contents as this string, but is * guaranteed to be from a pool of unique strings. */ public native String intern();
If you can't understand it, let's take a look at specific examples and analyze them.
public static void main(String[] args) { String s1 = new String("Java Charcoal burning"); s1.intern(); String s2 = "Java Charcoal burning"; System.out.println(s1 == s2); String s3 = new String("Java Charcoal burning") + new String("test"); s3.intern(); String s4 = "Java Charcoal burning test"; System.out.println(s3 == s4); }
Let's look at the results. The actual printing information is as follows.
Why do we show such results? Let's take a look. Therefore, in the jdk7 version, the string constant pool has been moved from the method area to the normal heap area.
##First false:
The first sentence is String s1 = new String("Java charcoal burning"); Two objects were generated. Java charcoal in the constant pool and string objects in the heap. s1.intern(); This sentence refers to the S1 object. After searching in the constant pool, it is found that "Java charcoal" is already in the constant pool. Next, String s2 = "Java charcoal burning"; This code generates an s2 reference to the "Java charcoal burning" object in the constant pool. The result is that the reference addresses of S and s2 are obviously different, so the print result is false.
##Second true:
Look at the s3 and s4 strings first. String s3 = new String("Java charcoal") + new String("test");, Three objects are now generated in this code, which are the objects pointed to by "Java charcoal", "test" in the string constant pool and s3 reference in the heap. At this time, the reference object content of s3 is "Java charcoal burning", but there is no "Java charcoal burning test" object in the constant pool. Next, s3 intern(); This code is to put the "Java charcoal burning" string in s3 into the string constant pool, because there is no "Java charcoal burning" string in the constant pool at this time. The constant pool does not need to store another object, but can directly store the references in the heap. This reference points to the object referenced by s3. That is, the reference address is the same. Finally, String s4 = "Java charcoal burning test"; In this code, "Java charcoal burning test" shows the declaration, so it will be directly created in the constant pool. When it is created, it is found that this object already exists. At this time, it is a reference to the s3 reference object. So the s4 reference points to the same as s3. So the final comparison s3 == s4 is true.
Let's see if the print results are different if we adjust the position of the above two lines of code.
public static void main(String[] args) { String s1 = new String("Java Charcoal burning"); String s2 = "Java Charcoal burning"; s1.intern(); System.out.println(s1 == s2); String s3 = new String("Java Charcoal burning") + new String("test"); String s4 = "Java Charcoal burning test"; s3.intern(); System.out.println(s3 == s4); }
The first false: in S1 and s2 codes, S1 intern();, This sentence will not have any impact if it is put back, because the first sentence of code String s = new String("Java charcoal burning") is being executed in the object pool; The "Java charcoal burning" object has been generated by. The s2 declarations below are referenced directly from the constant pool. The reference addresses of S and s2 will not be equal.
**The second false: * * the only difference from the above is s3 intern(); The sequence is String s4 = "Java charcoal test"; After that. In this way, first execute String s4 = "Java charcoal burning test"; When s4 is declared, the "Java charcoal burning test" object does not exist in the constant pool. After execution, the "little sister learning java test" object is a new object generated by s4 declaration. Then execute s3.intern(); when s4 is declared, the "Java charcoal burning test" object in the constant pool already exists, so the references of s3 and s4 are different.
#2. String, StringBuilder and StringBuffer
##2.1 inheritance structure
2.2 main differences
1) String is an immutable character sequence, and StringBuilder and StringBuffer are variable character sequences.
2) Execution speed StringBuilder > StringBuffer > string.
3) StringBuilder is non thread safe and StringBuffer is thread safe.
##Did you learn! If you think this article is useful to you, please give me some praise and attention, and there will be more my opinions on JAVA related knowledge in the future.
last
I also collected a core knowledge of Java interview to cope with the interview. I can give it to my readers for free by taking this opportunity:
catalog:
Core knowledge points of Java interview
There are 30 topics in total, which is enough for readers to cope with the interview and save time for friends to search for information everywhere and sort it out by themselves!
Core knowledge points of Java interview
Try, take this opportunity to give it to my readers for free:
catalog:
[external chain picture transferring... (img-h8u5jipH-1623618490326)]
Core knowledge points of Java interview
There are 30 topics in total, which is enough for readers to cope with the interview and save time for friends to search for information everywhere and sort it out by themselves!
[external chain picture transferring... (img-d0KIfLE1-1623618490327)]
Core knowledge points of Java interview
Data collection method: after likes[ Stamp interview data ]You can get it for free!