Preparing "golden nine silver ten" high-frequency surface 10 String resolve questions

Foreword

String is used in the development of our actual frequency is very high class, Java can be created by manipulating strings and the String class, the higher the frequency of use classes, the easier we ignore it, because it is more familiar to see, because of the familiarity, we think it is very simple, in fact, only learned fur, and did not really grasp, but String is a high-frequency test sites of the interview, so we need to study in depth the String class, completely buttoned, the lesson for everyone to explain in detail the core of String mechanisms and practical use.

v2-0444fec490c0aab587db00309d6fe8e3_hd.png

String three core:

1, invariance: String is read-only string, is a typical immutable objects, it do anything, in fact, is to create a new object, then references to the object. The main role of the same pattern is that when an object needs to be multi-threaded shared and frequent access, you can ensure data consistency.

2, constant pool optimization: String object is created later, will be cached in a string constant pool, if the next time you create the same objects will return a direct reference to the cache.

3, final: final use to define the String class, a String class can not be inherited, improving the security of the system.

String is not a primitive data types

This is very basic stuff, but it's easy to overlook a lot of beginners, eight basic data types not included in the Java String, basic data types used to describe text data is char, but it can only represent a single character, such as' a ',' good 'and the like, if a text to be described, you need to use a plurality of variable of type char, which is a char type array, such as "hello" is an array of length 2 of the char [] chars = { 'Hello there'};

However, using an array too cumbersome, so there String, String bottom is a type of char array, when developers just do not need to use the direct manipulation of the underlying array, with a more convenient way to complete use of the string.
Welcome to the concern I kind of public-ho [programmers] marks the beginning of the article will be updated on the inside, documentation will be on the inside.

v2-ed31b2ae83a26f2ace9fe0fa7a96aed9_hd.png

Frequency face questions

1、== 和 equals 的区别?

== 可以理解为是比较栈内存中的值,如果变量是基本数据类型,则栈内存中存放的就是具体数值,如果是引用类型,则栈中存放的是引用的内存地址。

所以对于基本数据类型,== 是比较值是否相等,对于引用数据类型,比较的是引用的内存地址是否相等。

v2-fa280936746a566a6bcef8a95ecf9604_hd.jpg

equals 是 Object 类提供的一个方法,其本质就是在用 == 进行判断。

public boolean equals(Object obj) {
  return (this == obj);
}

同时 Java 中任意一个类都可以对其进行重写,根据具体需求重新定义其判断逻辑,比如我们自定义一个 Student 类,如下所示。

public class Student {
    private Integer id;
    private String name;
    public Student(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
}

创建两个成员变量值完全相等的实例化对象,并用 equals 方法判断是否相等。

Student student1 = new Student(1,"张三");
Student student2 = new Student(1,"张三");
System.out.println(student1.equals(student2));

结果为 false,因为有两个实例化对象,就必然会在堆内存中开辟两块空间来存储,引用一定是不相同的。而在现实的逻辑中,如果两个学生的 id 和 name 都一样,我们就认为他们是同一个学生,用程序如何来实现呢?通过重写 equals 方法即可,如下所示。

public class Student {
    private Integer id;
    private String name;
    public Student(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
        Student student = (Student) obj;
        if(id.equals(student.id) && name.equals(student.name)){
            return true;
        }
        return false;
    }
}

再次运行代码,返回值为 true。

2、下面代码的运行结果是?

String str1 = "Hello World";
String str2 = "Hello"+" World";
System.out.println(str1 == str2);

true,"Hello" 和 " World" 都是字符串字面值,字符串字面值 + 字符串字面值的结果仍然保存在字符串常量池中,所以 str1 和 str2 相同。

3、下面代码的运行结果是?

v2-2d17731d7c5b464d4ec932f4c5ac6cfe_hd.png

String str1 = "Hello World";
String str2 = "Hello";
str2 += " World";
System.out.println(str1 == str2);

false,这题看似与第 2 题一样,为什么结果完全不同呢?因为 str2 = "Hello"+" World" 是直接创建,str2 = "Hello"; str2 = "Hello"; 是先创建再修改,同时修改完成之后的字符串是放在堆内存中的,为什么呢?因为 str2 是一个字符串变量," World" 是字符串字面值,当字符串字面值与 String 类型变量拼接时,得到的新字符串不再保存在常量池中,而是在堆中开辟一块新的空间来存储,所以 str1 引用指向字符串常量池,str2 引用指向堆内存,肯定不相同。

4、下面代码的运行结果是?

String str1 = "Hello World";
String str2 = " World";
String str3 = "Hello"+str2;
System.out.println(str1 == str3);

false,str2 是变量,"Hello" 是字符串字面值,字符串字面值 + 变量会在堆内存中开辟新的空间来存储,所以 str1 和 str3 不同。

5、下面代码的运行结果是?

String str1 = "Hello World";
final String str2 = " World";
String str3 = "Hello"+str2;
System.out.println(str1 == str3);

true,"Hello" 是字符串字面值,str2 是常量,字符串字面值+常量的结果仍然保存在字符串常量池中,所以 str1 和 str3 相同。

6、下面代码的运行结果是?

String str1 = "Hello World";
final String str2 = new String(" World");
String str3 = "Hello"+str2;
System.out.println(str1 == str3);

false,str2 是常量,但是 new String(" World") 保存在堆内存中,所以即使使用 final 进行了修饰,str2 仍然保存在堆中,则 str3 也就保存在堆中,所以 str1 和 str3 不同。

7、下面代码的运行结果是?

String str1 = "Hello World";
String str2 = "Hello";
String str3 = " World";
String str4 = str2 + str3;
System.out.println(str4.intern() == str1);

true,当调用 str4 的 intern 方法时,如果字符串常量池已经包含一个等于 str4 的字符串,则返回该字符串,否则将 str4 添加到字符串常量池中,并返回其引用,所以 str4.intern() 与 str1 相同。

8、什么是字符串常量池?

字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。

9、String 是线程安全的吗?

String 是不可变类,一旦创建了String对象,我们就无法改变它的值。因此它是线程安全的,同一个字符串实例可以被多个线程共享,保证了多线程的安全性。

10、在使用 HashMap 的时候,用 String 做 key 有什么好处?

HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。


最后

Welcome to share with everyone, like the point of a praise yo remember the article, thanks for the support!


Guess you like

Origin blog.51cto.com/14442094/2435954