Get to know String

1. Create a string

Common ways to construct String

// 方式一
String str = "abcd";
// 方式二
String str2 = new String("abcd");
// 方式三
char[] array = {
    
    'a', 'b', 'c'};
String str3 = new String(array);

Precautions:

String literal constants such as "hello" are of type String and
String is also a reference type. String str = "Hello";The memory layout of such code is as follows

Insert picture description here
Since String is a reference type, the
memory layout for the following code is as shown in the figure

String str1 = "Hello";
String str2 = str1;

Insert picture description here
But although both str1 and str2 point to "hello", "modifying" str2 will not affect str1

str2 = "world";
System.out.println(str2);
// 执行结果
Hello

Referencing a pointer similar to the C language, but opening up a small memory space on the stack to save an address.
In fact, the code like str1 = "world" does not count as "modifying" the string, but makes the reference of str1 point to a new String object.
Insert picture description here

2. String comparison is equal

If there are two int type variables, you can use == to complete the judgment of their equality.

int x = 10 ;
int y = 10 ;
System.out.println(x == y);
// 执行结果
true

But String comparison using == is not comparing the contents of the string, but comparing whether two references point to the same object . Use two codes to illustrate:
Code 1

String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2);
// 执行结果
true

Code 2

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2);
// 执行结果
false

Let's analyze the difference between the two ways of creating String.
Code 1 memory layout
Insert picture description here
We found that str1 and str2 point to the same object. At this time, such as "Hello" is a string constant in such a string constant pool of.

Regarding the string constant pool, string literal constants
such as "Hello" also require a certain amount of memory space to store. Such a constant has a characteristic, that is, it does not need to be modified. So if there are multiple references in the code that need to use "Hello", just refer to this location in the constant pool directly, and there is no need to store "Hello" twice in memory.

Code 2 memory layout
Insert picture description here
by String str1 = new String("Hello");the String object created in this way is equivalent to the heap another opened up a space to store the value "hello", so the contents of str1 and str2 are not the same.
If you want to compare the contents of strings in Java, you must use the equalsmethods provided by the String class .

Precautions for using equals

String str = new String("Hello");
// 方式一
System.out.println(str.equals("Hello"));
// 方式二
System.out.println("Hello".equals(str));

Both methods are possible, but we recommend method two more.

String str = null;
// 方式一
System.out.println(str.equals("Hello"));  
// 执行结果 抛出java.lang.NullPointerException 异常
// 方式二
System.out.println("Hello".equals(str));
//执行结果:false

Note: "Hello" literal constants like this, in essence, is a String object, you can use equalssuch as Stringobject methods

3. String constant pool

In the above example, the two examples of operation of the String class, direct assignment and newa newString

a) Direct assignment

String str1 = "hello" ;
String str2 = "hello" ;
String str3 = "hello" ;
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // true
System.out.println(str2 == str3); // true

Insert picture description here
The design of the String class uses a shared design pattern.
In fact, an object pool (string constant pool) is automatically maintained at the bottom of the JVM.

If the direct assignment mode is now used to instantiate an object of the String class, then the instantiated object (string content) will be automatically saved in this object pool.
If you continue to use the direct assignment mode to declare String objects next time, if there is specified content in the object pool at this time, it will be directly referenced.
If not, create a new string object and save it in the object pool for next use.

b) Adopt the construction method

It is standard practice for class objects to be instantiated using constructors. Analyze the following procedures:

String str = new String("hello");

Insert picture description here
This approach has two disadvantages:

  1. If you use the String construction method, two heap memory spaces will be opened up.
  2. String sharing problem. The same string may be stored multiple times, which is a waste of space.

We can use the String internmethods to manually added to the String object string constant pool

String str1 = new String("hello") ;// 该字符串常量并没有保存在对象池之中
String str2 = "hello" ;
System.out.println(str1 == str2);
// 执行结果
false
    
String str1 = new String("hello").intern() ;
String str2 = "hello" ;
System.out.println(str1 == str2);
// 执行结果
true

Interview question: Please explain the difference between the instantiation of the two types of objects in the String class

  1. Direct assignment: Only a piece of heap memory space will be opened, and the string object can be automatically saved in the object pool for next use.
  2. Construction method: Two heap memory spaces will be opened up and will not be automatically saved in the object pool. You can use the intern() method to manually enter the pool.

4. Understand immutable strings

A string is an immutable object. Its content cannot be changed.
The internal implementation of the String class is also based on char[], but the String class does not provide a set method or the like to modify the internal character array.

String str = "hello" ;
str = str + " world" ;
str += "!!!" ;
System.out.println(str);
// 执行结果
hello world!!!

An operation in the form of += seems to modify the string on the surface, but it is not. The memory changes are as follows:
Insert picture description here
first store "hello" in, store the stored reference to str, then store "world" in, concatenate it into "hello world", put the reference of "hello world" to str, and then put "!! !" is stored in, and the reference after splicing is given to str.
Therefore, the result printed by str after += has changed, but it is not the String object itself that has changed, but that str refers to other objects.

Recalling references A
reference is equivalent to a pointer, and the content stored in it is an address. We have to distinguish clearly whether the current modification is whether the content of the memory corresponding to the modified address has changed, or whether the address stored in the reference has changed.

If you really need to modify the string
a) Common method : use the original string to create a new string

String str = "Hello";
str = "h" + str.substring(1);
System.out.println(str);
// 执行结果
hello

b) Special method (optional): Using operations such as "reflection" can break the encapsulation and access private members within a class.
In IDEA, ctrl + left-click to jump to the definition of the String class, you can see that a char[] is included inside, which saves the content of the string.
Insert picture description here

String str = "Hello";
// 获取 String 类中的 value 字段. 这个 value 和 String 源码中的 value 是匹配的
Field valueField=String.class.getDeclaredField("value");
// 将这个字段的访问属性设为 true
valueField.setAccessible(true);
// 把 str 中的 value 属性获取到.
char[] value = (char[]) valueField.get(str);
// 修改 value 的值
value[0] = 'h';
System.out.println(str);
// 执行结果
hello

Benefits of immutable objects:

  1. It is convenient to realize the string object pool. If the String is variable, then the object pool needs to consider when to deep copy the string.
  2. Immutable objects are thread-safe.
  3. Immutable objects are more convenient to cache hash code, and can be stored in HashMap more efficiently when used as keys

5. Characters, bytes and strings

5.1 Characters and strings

The string contains an array of characters, and String can be converted to char[].

No Method name Types of description
1 public String(char value[]) structure Turn everything in the array into a string
2 public String(char value[],int offset,int count) structure Part of the contents of the character array into a string
3 public char charAt(int index) ordinary Get the character at the specified index position, the index starts from 0
4 public char[] toCharArray() ordinary Return the string into a character array

5.2 Bytes and strings

No Method name Types of description
1 public String(byte bytes[]) structure Turn byte array into string
2 public String(byte bytes[],int offset,int length) structure Turn the contents of part of the byte array into a string
3 public byte[] getBytes() ordinary Return the string as a byte array
4 public byte[] getBytes(String charsetName)throw UnsupportedEncodingException ordinary Transcoding processing

6. Common String Operations

6.1 String comparison

No Method name Types of description
1 public boolean equals(Object anObject) ordinary Case-sensitive comparison
2 public boolean equalsIgnoreCase(String anotherString) ordinary Case-insensitive comparison
3 public int compareTo(String anotherString) ordinary Compare the size of two strings

The compareTo()method in the String class is a very important method, the method returns an integer, the data will return three types of content according to the size relationship:

  1. Equal: return 0.
  2. Less than: The returned content is less than 0.
  3. Greater than: The returned content is greater than 0.

6.2 String search

No Method name Types of description
1 public boolean contains(CharSequence s) ordinary Determine whether a substring exists
2 public int indexOf(String str) ordinary Search the position of the specified string from the beginning, find the starting index of the returned position, and return -1 if not found
3 public int indexOf(String stx,int fromIndex) ordinary Find the position of the substring starting from the specified position
4 public int lastIndexOf(String str) ordinary Find the position of the substring from back to front
5 public int lastIndexOf(String str,int fromIndex) ordinary Search backward from the specified position
6 public boolean startsWith(String: prefix) ordinary Determine whether to start with the specified string
7 public boolean startsWith(String prefix, int toffset) ordinary Start from the specified position to determine whether it starts with the specified string
8 public boolean endsWith(String suffix) ordinary Determine whether to end with the specified string

6.3 String replacement

No Method name Types of description
1. public String replaceAll(String regex, String replacement) ordinary Replace all specified content
2. public String replaceFirst(String regex,String replacement) ordinary Replace the first content

6.4 String split

No Method name Types of description
1 public String[] split(String regex) 普通 将字符串全部拆分
2 public String[] split(String regex, int limit) 普通 将字符串部分拆分,该数组长度就是 limit 极限

6.5 字符串截取

No 方法名称 类型 描述
1 public String substring(int beginIndex) 普通 从指定索引截取到结尾
2 public String substring(int beginIndex, int endIndex) 普通 截取部分内容

6.6 其他操作方法

No 方法名称 类型 描述
1 public Stringtrim() 普通 去掉字符串中的左右空格,保留中间空格
2 public String toUpperCase() 普通 字符串转大写
3 public String toLowerCase() 普通 字符串转小写
4 public native String intern() 普通 字符串入池操作
5 public String concat(String str) 普通 字符串连接,等同于“+=”,不入池
6 public int length() 普通 取得字符串长度
7 public boolean isEmpty() 普通 判断是否为空字符串,但不是null,而是长度为0

7. StringBuffer 和 StringBuilder

首先来回顾下String类的特点:

  • 任何的字符串常量都是String对象,而且String的常量一旦声明不可改变,如果改变对象内容,改变的是其引用的指向而已。

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBufferStringBuilder类。
StringBufferStringBuilder 大部分功能是相同的,主要介绍 StringBuffer

在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法:

public synchronized StringBuffer append(各种数据类型 b)

The biggest difference between String and StringBuffer is that the content of String cannot be modified, while the content of StringBuffer can be modified. Consider using StingBuffer if you frequently modify strings.

Note: The String and StringBuffer classes cannot be converted directly. If you want to convert between each other, you can use the following principles:

String becomes StringBuffer: use StringBuffer's construction method or append() method
StringBuffer becomes String: call toString() method

In addition to the append() method, StringBuffer also has some methods that the String class does not:

  • String reversal:
public synchronized StringBuffer reverse()
  • Delete the data in the specified range:
public synchronized StringBuffer delete(int start, int end)
  • Insert data
public synchronized StringBuffer insert(int offset, 各种数据类型 b)

Interview question: Please explain the difference between String, StringBuffer and StringBuilder:

  • The content of String cannot be modified, and the content of StringBuffer and StringBuilder can be modified.
  • Most functions of StringBuffer and StringBuilder are similar
  • StringBuffer uses synchronous processing, which is a thread-safe operation; while StringBuilder does not use synchronous processing, which is a thread-unsafe operation

Guess you like

Origin blog.csdn.net/XKA_HRX/article/details/112961314