[Eight-part essay--Java basic interview questions (53 questions)]

Article directory

Java basic interview questions (53 questions)

Java overview

1. What is Java

image-20230814153835156

Java is an object-oriented programming language. It not only absorbs the various advantages of the C++ language, but also abandons the difficult-to-understand concepts such as multiple inheritance and pointers in C++. Therefore, the Java language has two characteristics: powerful functions and simple and easy to use. As an excellent representative of static object-oriented programming languages, Java language excellently implements object-oriented theory and allows programmers to perform complex programming with an elegant way of thinking.

2. What are the characteristics of Java language?

The Java language has many excellent features, among which the following are more prominent:

image-20230814154032044

  • Object-oriented (encapsulation, inheritance, polymorphism);
  • Platform independence. The specific manifestation of platform independence is that Java is a "Write Once, Run Any Where" language. Therefore, programs written in the Java language have good portability and ensure that this The point is Java's virtual mechanism. After the introduction of virtual machines, the Java language does not need to be recompiled to run on different platforms.
  • Supports multi-threading. The C++ language does not have a built-in multi-threading mechanism, so the multi-threading function of the operating system must be called for multi-thread programming, but the Java language provides multi-threading support;
  • Compilation and interpretation coexist;

3. What is the difference between JVM, JDK and JRE?

image-20230814154819487

  • JVM: Java Virtual Machine , Java virtual machine, Java programs run on the Java virtual machine. Different JVMs are implemented for different systems (Windows, Linux, macOS), so the Java language can be cross-platform.
  • JRE: Java Runtime Environment . It is a collection of everything needed to run a compiled Java program, including the Java Virtual Machine (JVM), Java class libraries, Java commands, and other basic building blocks. However, it cannot be used to create new programs.
  • JDK: Java Development Kit , it is a full-featured Java SDK. It has everything a JRE has, plus a compiler (javac) and tools (like javadoc and jdb). It can create and compile programs.

Simply put, JDK contains JRE, and JRE contains JVM

4. What is cross-platform? What is the principle

The so-called cross-platform means that a program written in Java language can run on multiple system platforms after being compiled once.
Implementation principle: Java programs are run on the system platform through the Java virtual machine. As long as the system can install the corresponding Java virtual machine, the system can run the java program.

5. What is bytecode? What are the benefits of using bytecode?

The so-called bytecode is a .class file generated by compiling a Java program. The bytecode can be recognized by the virtual machine, thereby realizing the cross-platform nature of the Java program.

There are three main steps from source code to running a Java program:

  • Compilation: Compile our code (.java) into bytecode (.class) that the virtual machine can recognize and understand.
  • Explanation: The virtual machine executes Java bytecode and translates the bytecode into machine code that the machine can recognize.
  • Execution: The corresponding machine executes the binary machine code

image-20230814155131899

You only need to compile the Java program into Java bytecode that can be recognized by the Java virtual machine, and install the corresponding Java virtual machine for different platforms, so that the platform independence of the Java language can be achieved.

6. Why is it said that Java language "compilation and interpretation coexist"?

image-20230814160031599

High-level programming languages ​​are divided into two types : compiled and interpreted according to the execution mode of the program .

simply put:

  • Compiled language means that the compiler translates the source code into machine code that can be executed by the platform at one time for a specific operating system;
  • An interpreted language means that the interpreter interprets the source program line by line into machine code for a specific platform and executes it immediately.

For example, if you want to read a foreign novel, you can find a translator to help you translate it. There are two options. You can first wait for the translator to translate the entire novel (that is, the source code) into Chinese, and then go to For reading, you can also ask a translator to translate a paragraph, while you read a paragraph next to you and slowly finish the book.

The Java language has the characteristics of both a compiled language and an interpreted language, because Java programs need to go through two steps: first compilation and then interpretation. Programs written in Java need to first go through the compilation step to generate bytecode (*. class file), this bytecode must go through the JVM and be interpreted into machine code that the operating system can recognize, and then executed by the operating system. Therefore, we can think that Java language compilation and interpretation coexist.

basic grammar

7. What data types does Java have?

Definition : The Java language is a strongly typed language. A clear and specific data type is defined for each type of data , and different sizes of memory space are allocated in the memory.

Java language data types are divided into two types: basic data types and reference data types .

image-20230814160721612

Basic data types:

  • Numerical type
    • Integer type (byte, short, int, long)
    • Floating point type (float, double)
  • Character type (char)
  • boolean

Java basic data type ranges and default values:

image-20230814160615003

Reference data type:

  • class
  • interface
  • array([])

8. Automatic type conversion or forced type conversion? Look at these lines of code?

All numerical variables in Java can be converted to each other. When a value or variable with a small table number range is directly assigned to another variable with a large table number range, automatic type conversion can be performed; otherwise, forced conversion is required.

image-20230814160932762

It's like pouring water from a small cup into a large cup is fine, but pouring water from a large cup into a small cup is not possible and may overflow.

float f=3.4, right?

Incorrect. 3.4 is a single-precision number. Assigning a double to a float is down-casting (also called narrowing), which will cause precision loss, so forced type conversion is required.

float f = (float) 3.4; or written as float f =3.4F short s1 = 1; s1 = s1 + 1; right? short s1 = 1; s1 += 1; right?

For short s1 = 1; s1 = s1 + 1; a compilation error occurs. Since 1 is of type int, the result of the s1+1 operation is also of type int, and the type needs to be forced to be assigned to the short type.

And short s1 = 1; s1 += 1; compiles correctly because s1+= 1; is equivalent to s1 = (short (s1 + 1); which has an implicit cast.

9. What is automatic unboxing/sealing?

  • Boxing : Wrapping basic types with their corresponding reference types;
  • Unboxing : Convert the packed type to a basic data type;

Java can automatically box and unbox basic data types and their wrapper classes.

image-20230814162123779

Example:

Integer i = 1; //装箱
int n = i;	   //拆箱	

10. What is the difference between & and &&?

&The operator has two uses: 短路与, 逻辑与.

&&The operator is 短路与运算. The difference between logical AND and short-circuit AND is very huge, although both require that the Boolean values ​​on the left and right sides of the operator are true, and the value of the entire expression is true.

&& is called a short-circuit operation because if the value of the expression on the left side of && is false, the expression on the right side will be directly short-circuited and no operation will be performed . Many times we may need to use && instead of &.

For example, when verifying user login, it is determined that the user name is not null and not an empty string. It should be written as, the username!= null && !username.equals("")order of the two cannot be exchanged, and the & operator cannot be used, because if the first condition is not established, string equals cannot be performed at all. Compare, otherwise a NullPointerException will be generated.
Note: The same is true for the difference between the logical OR operator (|) and the short-circuit OR operator (||).

11. Can switch work on byte/long/String?

Before Java5, in switch(expr), expr could only be byte, short, char, or int.

Starting from Java 5, enumeration types were introduced in Java, and expr can also be an enum type.

Starting from Java 7, expr can also be a string (String), but a long integer (long) is not allowed in all current versions.

12. What are the differences and functions of break, continue, and return?

image-20230814162648223

  • break jumps out of the entire loop and no longer executes the loop (ends the current loop body)
  • continue to jump out of this loop and continue to execute the next loop (end the executing loop and enter the next loop condition)
  • return The program returns and no longer executes the following code (ends the current method and returns directly)

13. What is the most efficient way to multiply 2 by 8?

2<<3. Bitwise operations, shifting the binary digits of a number to the left by three bits is equivalent to multiplying by 2 raised to the third power.

14. Talk about self-increment and self-decrement operations? Take a look at the results of running these codes?

In the process of writing code, a common situation is to need an integer type variable to increase or decrease by 1. Java provides a special operator for this kind of expression, called the increment operator (++ ) and the decrement operator (–).

The ++ and – operators can be placed before or after a variable.

When the operator is placed before the variable (prefix), it is incremented/decremented first, and then assigned; when the operator is placed after the variable (suffix), it is assigned first, and then incremented/decremented.

For example, when b = ++a, first increment (increment by 1) and then assign (assign to b); when b = a++, first assign (assign to b) and then increment (increment by 1). That is, ++a outputs the value of a+1, and a++ outputs the value of a.

A mantra is: "If the symbol comes first, add/subtract first; if the symbol comes after, add/subtract last."

Take a look at the results of this code?

int i = 1; 
i = i++; 
System. out. println(i);

The answer is 1. A bit outrageous, right?

For the JVM, its processing of the auto-increment operation is to first define a temporary variable to receive the value of i, then perform the auto-increment operation, and finally assign the temporary variable to i with a value of 2, so the final result is 1.

Equivalent to code like this:

int i = 1;
int temp = i;
i++;
i = temp;
System.out.println(i);

What will this code output?

int count = 0;
for(int i = 0;i < 100;i++)
{
    
    
	count = count++;
}
System.out.println("count = "+count);

The answer is 0.

The same reason as the above question, also uses temporary variables, count is actually equal to the value of the temporary variable.

Similar to:

int autoAdd(int count)
{
    
    
    int temp = count;
    count = coutn + 1;
    return temp;
}

object-oriented

15. What is the difference between object-oriented and process-oriented?

  • Process-oriented : Process-oriented is to analyze the steps required to solve the problem, and then use functions to implement these steps step by step. When using them, just call them one by one.
  • Object-oriented : Object-oriented, decomposes the transactions that constitute the problem into individual objects, and the purpose of establishing objects is not to complete each step, but to describe the behavior of a certain event in the process of solving the entire problem. The purpose is to write universal code, enhance code reuse, and shield differences .

Use an analogy: process-oriented is a chronological style; object-oriented is a biographical style.

16. What are the characteristics of object-oriented

image-20230814163551103

  • encapsulation

    Encapsulation privatizes the properties of an object and provides methods for properties that can be accessed by the outside world.

  • inherit

    Inheritance is the creation of a new class using the definition of an existing class as a basis. The definition of a new class can add new attributes or new methods, or it can inherit the attributes and methods of the parent class. Code reuse can be easily achieved through inheritance.

There are three main points about inheritance:

  1. The subclass has all the properties and methods of the parent class object (including private properties and private methods), but the private properties and methods in the parent class are inaccessible to the subclass, only owned .
  2. Subclasses can have their own properties and methods, that is, subclasses can extend parent classes .
  3. Subclasses can implement the methods of the parent class in their own way .
  • Polymorphism
    The so-called polymorphism means that the specific type pointed to by the reference variable defined in the program and the method calls issued through the reference variable are not determined during programming, but are determined during the running of the program, that is, what will a reference variable point to ? The instance object of which class and the method call issued by the reference variable are the methods implemented in which class must be determined during the running of the program .

    There are two forms of polymorphism in Java: inheritance (overwriting of the same method by multiple subclasses) and interface (implementing an interface and overriding the same method in the interface) .

17. What is the difference between overload and override?

Method overloading and rewriting are both ways to achieve polymorphism . The difference is that the former implements compile-time polymorphism , while the latter implements run-time polymorphism .

  • Overloading occurs in a class. Methods with the same name are considered overloaded if they have different parameter lists (different parameter types, different number of parameters, or both);

  • Rewriting occurs between a subclass and a parent class. Rewriting requires that the overridden method of the subclass has the same return type as the overridden method of the parent class. It is easier to access than the overridden method of the parent class and cannot be used better than the overridden method of the parent class . Override methods to declare more exceptions (Liskov substitution principle) .

Rules for method overloading :

  1. The method names are the same, but the order, type, and number of parameters in the parameter list are different.
  2. Overloading has nothing to do with the return value of the method and exists in parent classes and subclasses of the same type.
  3. Different exceptions can be thrown and can have different modifiers.

18. What are the differences between the access modifiers public, private, protected, and not written (default)?

image-20230814164606139

In Java, access controls can be used to protect access to classes, variables, methods, and constructors. Java supports 4 different access rights.

  • default (i.e. default, write nothing): Visible within the same package, no modifiers are used. Can be modified on classes, interfaces, variables, and methods.
  • private : Visible within the same class. Variables and methods can be modified. Note: Classes (external classes) cannot be modified.
  • public : Visible to all classes. You can modify classes, interfaces, variables, and methods.
  • protected : Visible to classes and all subclasses in the same package. Variables and methods can be modified. Note: Classes (external classes) cannot be modified .

19. What does the this keyword do?

this is an object of its own, representing the object itself , and can be understood as: a pointer to the object itself .

The usage of this in Java can be roughly divided into three types:

  1. Ordinary direct reference, this is equivalent to pointing to the current object itself
  2. If the names of formal participating member variables have the same name, use this to distinguish them:
public Person(String name,int age){
    
    
    this.name=name;
    this.age=age;
}
  1. Reference the constructor of this class

20. What is the difference between abstract class and interface?

  1. Interface methods are public by default , and all methods cannot be implemented in the interface (interface methods can have default implementations starting from Java 8), while abstract classes can have non-abstract methods .
  2. In addition to static and final variables, there cannot be other variables in the interface, but not necessarily in the abstract class .
  3. A class can implement multiple interfaces, but can only implement one abstract class . The interface itself can extend multiple interfaces through the extends keyword.
  4. The default modifier for interface methods is public, and abstract methods can have the modifiers public, protected, and default ( abstract methods are meant to be overridden, so they cannot be modified with the private keyword! ).
  5. From a design perspective, abstraction is the abstraction of classes and a template design , while interfaces are the abstraction of behavior and a specification of behavior .
  1. In JDK8, interfaces can also define static methods, which can be called directly using the interface name. Implementation classes and implementation methods cannot be called. If two interfaces are implemented at the same time and the same default method is defined in the interface, they must be rewritten, otherwise an error will be reported.
  2. Interfaces in jdk9 are allowed to define private methods.

Summarize the changes in interfaces in jdk7-jdk9 Java:

  1. In jdk 7 or earlier, only constant variables and abstract methods can be found in interfaces. These interface methods must be implemented by the class that chooses to implement the interface.
  2. In jdk 8, interfaces can have default methods and static method functions.
  3. jdk 9 introduced private methods and private static methods in interfaces.

21. What are the differences between member variables and local variables?

  1. From a grammatical point of view : member variables belong to the class, while local variables are variables defined in the method or parameters of the method; member variables can be modified by public, private, static and other modifiers, but local variables cannot be accessed Modified by control modifier and static; however, member variables and local variables can be modified by final .
  2. Judging from the way variables are stored in memory : if the member variable is modified with static, then the member variable belongs to the class . If it is not modified with static, the member variable belongs to the instance. The object is stored in the heap memory. If the local variable type is a basic data type, it is stored in the stack memory. If it is a reference data type, it stores a reference to the heap memory object or an address in the constant pool .
  3. From the perspective of the survival time of variables in memory : member variables are part of the object and exist with the creation of the object, while local variables disappear automatically as the method is called.
  4. If a member variable is not assigned an initial value , it will be automatically assigned a value based on the default value of the type (one exception: member variables modified by final must also be assigned a value explicitly), while local variables will not be assigned a value automatically.

22. What is the difference between static variables and instance variables? What about static methods and instance methods?

What is the difference between static variables and instance variables?

  • Static variable : It is a variable modified by the static modifier, also called a class variable. It belongs to the class and does not belong to any number of objects of the class. Static variables have and only one copy in memory.
  • Instance variables : must depend on an instance. You need to create an object first and then access it through the object. Static variables allow multiple objects to share memory.

What is the difference between static methods and instance methods?

Similarly.

  • Static method : static modified method, also known as class method. When calling a static method externally, you can use the " class name.method name " method or the " object name·method name " method. Non-static member variables and methods of the class cannot be accessed in static methods .
  • Instance method : It depends on the instance of the class and needs to be called using " object name.method name "; it can access all member variables and methods of the class.

24. What is the function of final keyword?

image-20230814172400206

final means immutable and can be used to modify classes, properties and methods:

  • Classes modified by final cannot be inherited
  • Methods modified by final cannot be overridden
  • Variables modified by final are immutable. Variables modified by final must have an initial value explicitly specified. It should also be noted that immutability here refers to the immutability of the reference to the variable, not the immutability of the content pointed to by the reference .
    For example:
final StringBuilder sb = new StringBuilder("abc"); 
sb.append ("d"); 
System.out.println(sb); //abcd

25. What is the difference between final, finally and finalize?

  • **final ** is used to modify variables, methods and classes: classes modified by final cannot be inherited; modified methods cannot be overridden; modified variables are immutable.

  • Finally, as part of exception handling, it can only be used in try/catch statements, and is accompanied by a statement block to indicate that this statement will eventually be executed (regardless of whether an exception is thrown). It is often used when resources need to be released . System .exit(0) can block finally execution.

  • finalize is a method defined in java.lang.Object, which means that every object has such a method. This method is called when gc is started and the object is recycled .

    The finalize method of an object will only be called once. When finalize is called, the object may not be recycled immediately. Therefore, it is possible that after finalize is called, the object does not need to be recycled, and then when it is actually time to be recycled, because the previous call Once, finalize will not be called again, which will cause problems, so the finalize method is not recommended .

26. What is the difference between == and equals?

== : Its function is to determine whether the addresses of two objects are equal . That is, determine whether two objects are the same object (basic data type **== compares values, reference data type ==** compares memory addresses).

equals() : Its function is also to determine whether two objects are equal. But this "equality" generally falls into two situations:

  • Default: The class does not override the equals() method. Then comparing two objects of this class through equals() is equivalent to comparing the two objects through "==", or comparing memory addresses.
  • Custom case: The class overrides the equals() method. The equals() method we usually cover usually compares whether the contents of two objects are the same, and defines an equality standard, that is, whether the values ​​of the two objects are equal.

For example, Person, we think that two people with the same number and name are one person:

public class Person {
    
    
    private String no;
    private String name;
    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
    	return Objects.equals(no, person.no) &&
    			Objects.equals(name, person.name);
    }
    @Override
    public int hashCode() {
    
    
    	return Objects.hash(no, name);
    }
}

27. hashCode 与 equals?

This is also a common interview question - "Have you ever rewritten hashcode and equals? Why do you have to rewrite the hashCode method when rewriting equals?"

What is HashCode?

The function of hashCode() is to obtain the hash code, also called hash code; it actually returns an int integer, which is defined in the Object class and is a local method. This method is usually used to convert the memory address of the object into Return after the integer .

public native int hashCode();

Hash codes are mainly used when mapping sets such as hash tables. Hash tables store key-value pairs. Its characteristics are: it can quickly map to the corresponding "value" according to the "key". ". This uses hash codes!

Why do we need hashCode?

As mentioned above, it is mainly used in structures such as hash tables.
For example, how does HashMap map keys to corresponding values? What is used is the hash remainder method, which is to take the remainder of the hash code and the length of the array storing the element to obtain the subscript position of the value corresponding to the key.

Why do I have to override the hashCode method when overriding equals?

If two objects are equal, the hashcode must also be the same . If two objects are equal, calling the equals method on both objects will return true. On the contrary, if two objects have the same hashcode value, they are not necessarily equal . Therefore, if the equals method is overridden, the hashCode method must also be overridden.

The default behavior of hashCode() is to produce unique values ​​for objects on the heap. If hashCode() is not overridden, the two objects of this class will not be equal anyway (even if the two objects point to the same data)

Why are two objects with the same hashcode value not necessarily equal?

Because of possible collisions, the hashing algorithm used by hashCode() may just cause multiple objects to return the same hash value. The worse the hash algorithm is, the easier it is to collide, but this is also related to the characteristics of the data range distribution (the so-called collision means that different objects get the same hashCode().

28. Is Java passed by value or by reference?

The Java language is pass-by-value . Method calls in the Java language only support passing parameters by value . When an object instance is passed as a parameter to a method, the parameter's value is a reference to the object . The properties of the object can be changed during the call, but changes to the object reference will not affect the caller .

The memory of the JVM is divided into a heap and a stack. The stack stores the addresses of basic data types and reference data type instances , that is, object addresses.
The space occupied by the object is opened in the heap, so when passing it, it can be understood as passing the object address stored in the variable, so the reference type is also passed by value.

image-20230814200059010

29. Deep copy and shallow copy?

  • Shallow copy : Only the values ​​of the member variables of the copied object are copied, that is, the values ​​of the basic data type variables and the address values ​​of the reference data type variables, but the objects in the heap pointed to by the reference type variables are not copied .
  • Deep copy : Completely copies an object, copies the values ​​of member variables of the copied object, and copies objects in the heap.

For example, there is an order object, which contains a products list, and its shallow copy and deep copy diagram:

image-20230814200955442

Therefore, deep copy is safe. If there is a reference type in shallow copy, then the copied object and reference type variable modification will affect the original object.

How to implement shallow copy?

The clone() method provided by the Object class can realize a shallow copy of the object very simply.

How to implement deep copy?

  • Rewrite the clone method: Rewrite the clone method and clone the reference type variables separately, which may involve multiple levels of recursion.

  • Serialization: You can first serialize the original object and then deserialize it into a copy object.

30. What are the ways to create objects in Java?

There are four ways to create objects in Java:

image-20230814201316083

  • new creates a new object
  • through reflection mechanism
  • Using clone mechanism
  • through serialization mechanism

The first two require explicit calls to the constructor.

For the clone mechanism, you need to pay attention to the difference between shallow copy and deep copy. For the serialization mechanism, you need to clarify its implementation principle. Serialization in Java can be achieved by implementing Externalizable or Serializable.

String

31. Is String a basic data type in Java? Can it be inherited?

Is String a basic data type in Java?

no. There are only 8 basic data types in Java: byte, short, int, long, float, double, char, boolean; except for primitive types, the rest are reference types.

String is a special reference data type.

Can the String class be inherited?

no. The String class is decorated with final and is a so-called immutable class that cannot be inherited .

32. What is the difference between String, StringBuilder and StringBuffer?

  • String : The value of String cannot be modified after it is created. Any modification to String will cause the generation of a new String object.
  • StringBuffer : Similar to String, but the value can be modified, using synchronized to ensure thread safety .
  • StringBuilder : A non-thread-safe version of StringBuffer with higher performance .

33. What is the difference between String str1 = new String("abc") and String str2="abc"?

Both statements will check whether "abc" already exists in the string constant pool. If it exists, it will be used directly. If not, the "abc" object will be created in the constant pool.

[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-hSpOr4cc-1692104323159) (C:%5CUsers%5CA%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images% 5Cimage-20230814201830290.png)]

But the difference is that String str1 = new String("abc") will also create an "abc" string object instance in the heap through new String(). So the latter can be understood as being included by the former.

How many objects does String s = new String("abc") create?

Obviously, one or two. One if the string constant pool already has "abc"; otherwise, two.

When the character creation constant pool does not have "abc", the following two objects will be created:

  • One is the instance in the string constant pool corresponding to the string literal "abc"
  • The other is an instance created and initialized via new String() with the same content as "abc", in the heap.

34. Isn’t String an immutable class? How is string concatenation implemented?

String is indeed immutable, and the "+" splicing operation will actually generate a new object.
For example:

String a = "hello ";
String b = "world!";
String ab = a + b;

Before jdk1.8, a and b were located in the string constant pool when initialized, and the spliced ​​object ab was located in the heap. After splicing, a new String object is generated. If spliced ​​multiple times, multiple intermediate objects will be generated.

The memory is as follows:

image-20230814202257315

In Java 8, the JDK optimized the "+" sign splicing, and the splicing method written above will be optimized to be processed based on the append method of StringBuilder . Java will process the "+" sign at compile time.

The following is the result of decompiling the bytecode through the javap -verbose command. It is obvious that the creation of StringBuilder and the call of the append method can be seen.

stack=2, locals=4, args_size=1
0: ldc #2 // String hello
2: astore_1
3: ldc #3 // String world!
5: astore_2
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."<init>":
()V
13: aload_1
14: invokevirtual #6 // Method java/lang/StringBuilder.append:
(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6 // Method java/lang/StringBuilder.append:
(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7 // Method java/lang/StringBuilder.toString:
()Ljava/lang/String;
24: astore_3
25: return

In other words, the above code is actually equivalent to:

String a = "hello ";
String b = "world!";
StringBuilder sb = new StringBuilder();
sb.append(a);
sb.append(b);
String ab = sb.toString();

At this point, it would be wrong to give a general answer: concatenating strings with the plus sign will create multiple String objects, so the performance is worse than StringBuilder. Because essentially the effect of plus sign splicing is the same as StringBuilder after being processed by the compiler.

Of course, it is recommended to use StringBuilder for splicing in a loop. Why? Because a new StringBuilder object will be created once the loop is executed. You can experiment by yourself.

35. What does the intern method do?

This method has been explained in the JDK source code:

* <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>

The meaning is also easy to understand:

  • If the current string content exists in the string constant pool (that is, the equals() method is true, that is, the content is the same), directly return the string in the string constant pool.
  • Otherwise, adds this String object to the pool and returns a reference to the String object

Integer

36. Integer a= 127, Integer b=127; Integer c= 128, Integer d =128;, are they equal?

The answer is that a and b are equal, but c and d are not equal.

  • For basic data types == compared values
  • For reference data types == compares addresses

The assignment of Integer a = 127 uses the Integer automatic boxing mechanism. During auto-boxing, the Integer object will be retrieved from the cache pool. If the Integer object is not retrieved, a new object will be created.

If the value of the integer literal is between -128 and 127 , then the new Integer object will not be new during automatic boxing, but will directly reference the Integer object in the cache pool. The result exceeding the range a1==b1 is false.

public static void main(String[] args) {
    
    
    Integer a = 127;
    Integer b = 127;
    Integer b1 = new Integer(127);
    System.out.println(a == b); //true
    System.out.println(b==b1); //false
    Integer c = 128;
    Integer d = 128;
    System.out.println(c == d); //false
}

What is Integer cache?

Because according to practice, it is found that most data operations are concentrated in a relatively small value range, so Integer has a cache pool. The default range is -128 to 127.

JVM-XX:AutoBoxCacheMax=The maximum value of the cache can be modified according to the settings , but the minimum value cannot be changed.

The principle of implementation is that int will be called during automatic boxing Integer.valueOf, and then used IntegerCache.

public static Integer valueOf(int i) {
    
    
    if (i >= IntegerCache.low && i <= IntegerCache.high)
    	return IntegerCache.cache[i + (-IntegerCache.low)]; 
    return new Integer(i);
}

It's very simple, just check whether the value is within the cache range, if so, IntegerCacheget it, if not, create a new Integer object.

IntegerCacheIt is a static inner class, and the cache value will be initialized in the static block.

private static class IntegerCache {
    
    
    ……
    static {
    
    
        //创建Integer对象存储
        for(int k = 0; k < cache.length; k++)
        	cache[k] = new Integer(j++);
        ……
    }
}

37. How to convert String to Integer? principle?

There are two main methods for converting String to Integer:

  • Integer.parselnt(String s)
  • Integer.valueOf(String s)

No matter which one, the method in the Integer class will eventually be called parseInt(String s, int radix).

Throw away some boundaries and the like and look at the core code:

public static int parseInt(String s, int radix) throws NumberFormatException
{
    
    
    int result = 0;
    //是否是负数
    boolean negative = false;
    //char字符数组下标和长度
    int i = 0, len = s.length();
    ……
    int digit;
    //判断字符长度是否大于0,否则抛出异常
    if (len > 0) {
    
    
        ……
        while (i < len) {
    
    
            // Accumulating negatively avoids surprises near MAX_VALUE
            //返回指定基数中字符表示的数值。(此处是十进制数值)
            digit = Character.digit(s.charAt(i++),radix);
            //进制位乘以数值
            result *= radix;
            result -= digit;
        }
    }
    //根据上面得到的是否负数,返回相应的值
    return negative ? result : -result;
}

After removing the branches and vines (of course you can check out these branches and vines, the source code covers many cases), what is left is actually a simple string traversal calculation, but the calculation method is a bit unconventional, using negative values ​​to accumulate.

image-20230814204443845

Object

38. What are the common methods of Object class?

The Object class is a special class and is the parent class of all classes, which means that all classes can call its methods. It mainly provides the following 11 methods, which can be roughly divided into six categories:

image-20230814204624015

Object comparison:

  • public native int hashCode(): native method, used to return the hash code of the object, mainly used in hash tables, such as HashMap in JDK.
  • public boolean equals(Object ob): Used to compare whether the memory addresses of two objects are equal. The String class overrides this method to compare whether the values ​​of strings are equal.

Object copy:

  • protected native Object clone() throws CloneNotSupportedException: native method, used to create and return a copy of the current object. In general, for any object x, the expression x.clone() != xis true, x.clone().getClass() == x.getClass()is true. Object itself does not implement the Cloneable interface, so if you do not override the clone method and call it, CloneNotSupportedExceptionan exception will occur.

Object to string:

  • public String toString(): Returns the hexadecimal string of the class name@instance hash code. It is recommended that all subclasses of Object override this method.

Multi-thread scheduling:

  • public final native void notify():native method and cannot be overridden. Wake up a thread waiting on this object's monitor (the monitor is equivalent to the concept of a lock). If there are multiple threads waiting, only one will be woken up at will .
  • public final native void notifyAll():native method and cannot be overridden. Like notify, the only difference is that it wakes up all threads waiting on this object monitor instead of just one thread.
  • public final native void wait(long timeout) throws InterruptedException:native method and cannot be overridden.
    Pauses the thread's execution. Note: The sleep method does not release the lock, but the wait method releases the lock . timeout is the waiting time.
  • public final void wait(long timeout, int nanos) throws InterruptedException: There is an additional nanos parameter, which represents additional time (in nanoseconds, range is 0-999999). Therefore, nanos milliseconds need to be added to the timeout.
  • public final void wait() throws InterruptedException: Same as the previous two wait methods, except that this method keeps waiting and has no concept of timeout.

reflection:

  • public final native Class<?> getClass():native method, used to return the Class object of the current runtime object, is modified with the final keyword, so subclasses are not allowed to override it.

Garbage collection:

  • protected void finalize() throws Throwable: Notify the garbage collector to recycle objects.

Exception handling

39. Exception handling system in Java?

Java's exception system is divided into multiple layers.

image-20230814205635873

ThrowableIs the base class for all errors or exceptions in the Java language. ThrowableIt is also divided into Errorand Exception, among which Error are system internal errors, such as virtual machine exceptions, which cannot be handled by the program. ExceptionIt is an exception caused by a program problem and is divided into two types:

  • CheckedExceptionChecked exceptions: Exceptions that the compiler forces to check and require handling.
  • RuntimeExceptionRuntime exception: Exceptions occur while the program is running, such as the familiar null pointer, array subscript out of bounds, etc.

40. How to handle exceptions?

There are two main ways to handle exceptions:

image-20230814205918229

  • When an exception is encountered, no specific handling is performed, but it continues to be thrown to the caller (throw, throws)

There are three forms of throwing exceptions, one is throw, the other is throws, and the system automatically throws exceptions.

throws is used on methods, followed by the exception class , which can be multiple; and throw is used within the method, followed by the exception object .

  • try catch catch exception

Catch the exception that occurs in the catch statement block and handle it.

try{
    
    
    //包含可能会出现异常的代码以及声明异常的方法
}catch(Exception e){
    
    
    //捕获异常并进行处理
}finally {
    
    
    //可选,必执行的代码
}

When try-catch catches an exception, you can also choose to add a finally statement block. The finally statement block will eventually be executed regardless of whether the program is executed normally.

41. Three classic exception handling code questions

Question 1

public class TryDemo {
    
    
    public static void main(String[] args) {
    
    
    	System.out.println(test());
    }
    public static int test() {
    
    
        try {
    
    
        	return 1;
        } catch (Exception e) {
    
    
        	return 2;
        } finally {
    
    
        	System.out.print("3");
        }
    }
}

Execution result: 31.
The basic usage of try, catch, and finally is that the finally statement block is executed before return, so the 3 in finally is output first, and then the 1 in return is output.

Question 2

public class TryDemo {
    
    
    public static void main(String[] args) {
    
    
        	System.out.println(test1());
        }
        public static int test1() {
    
    
            try {
    
    
                return 2;
            } finally {
    
    
                return 3;
            }
    }
}

Execution result: 3.
Try executes finally before returning. As a result, finally does not follow the routine and returns directly. Naturally, the return in try cannot be reached.

The use of return in finally only exists in interview questions. If you write this in actual development, you will be punished.

Question 3

public class TryDemo {
    
    
    public static void main(String[] args) {
    
    
    	System.out.println(test1());
    }
    public static int test1() {
    
    
        int i = 0;
        try {
    
    
        	i = 2;
        	return i;
        } finally {
    
    
        	i = 3;
        }
    }
}

Execution results: 2.
You may think that the result should be 3, because finally is executed before return, and i is modified to 3 in finally, so shouldn't the final returned i be 3?

But in fact, before executing finally, the JVM will temporarily store the result of i, and then after finally is executed, it will return the previously stored result instead of i, so even if i has been modified to 3, the final returned It is still the result 2 that was temporarily saved before.

I/O

42.How many types of IO streams are there in Java?

There are many ways to divide streams according to different characteristics.

  • According to the flow direction of the flow, it can be divided into input flow and output flow ;
  • According to the operation unit, it can be divided into byte stream and character stream ;
  • According to the role of the flow, it is divided into node flow and processing flow .

Java IO flow involves a total of more than 40 classes, which may seem messy, but in fact they are all related to a certain extent. The more than 40 classes of Java IO flow are derived from the following four abstract base classes.

  • InputStream/Reader: The base class of all input streams, the former is a byte input stream, and the latter is a character input stream.
  • OutputStream/Writer: The base class of all output streams, the former is a byte output stream, and the latter is a character output stream.

image-20230814212354747

What design patterns are used for IO streams?

In fact, Java's 10 stream system also uses a design pattern- the decorator pattern .

Some class diagrams related to InputStream are as follows. Due to limited space, the decorator mode will not be discussed in detail.

image-20230814212526493

43. Since there is a byte stream, why do we need a character stream?

In fact, the character stream is obtained by converting bytes by the Java virtual machine. The problem is that this process is relatively time-consuming, and if we do not know the encoding type, it is easy to cause garbled characters.

Therefore, the I/O stream simply provides an interface for directly operating characters, which facilitates our usual stream operations on characters. If audio files, pictures and other media files are better, it is better to use byte stream. If characters are involved, it is better to use character stream.

44. BIO、NIO、AIO?

image-20230814214051630

BIO (blocking I/O) : It is traditional IO, synchronous blocking, the server implementation mode is one connection and one thread, that is, when the client has a connection request, the server needs to start a thread for processing. If the connection does not do anything, it will This causes unnecessary thread overhead, which can be improved through the connection pool mechanism (to enable multiple clients to connect to the server).

image-20230814214224037

The BIO method is suitable for architectures with a relatively small and fixed number of connections. This method has relatively high requirements for server resources, and concurrency is limited to applications. It was the only choice before JDK1.4, and the program is simple and easy to understand.

NIO : The full name is java non-blocking IO, which refers to the new API provided by JDK. Starting from JDK1.4, Java provides a series of improved new input/output features, collectively called NIO (New IO).

NIO is synchronous and non-blocking . The server uses one thread to process multiple connections. The connection request sent by the client will be registered on the multiplexer. The multiplexer polls the connection and processes it if there is an O request:

image-20230814214428884

NIO data is buffer-oriented and must be read or written from the buffer.

So the complete NIO schematic:

image-20230814214920268

It can be seen that the operating mechanism of NIO:

  • Each Channel corresponds to a Buffer.
  • Selector corresponds to one thread, and one thread corresponds to multiple Channels.
  • Selector will switch on each channel according to different events.
  • Buffer is a memory block, and the bottom layer is data.

AIO : JDK7 introduced Asynchronous l/O, which is asynchronous non-blocking IO . In I/O programming, two modes are commonly used: Reactor and Proactor. Java's NIO is Reactor. When an event is triggered, the server is notified and performs corresponding processing. After completion, it notifies the server program to start a thread for processing. It is generally suitable for applications with a large number of connections and long connection times.

Serialization

45. What is serialization? What is deserialization?

What is serialization? Serialization is to convert Java objects into binary streams to facilitate storage and transmission.

So deserialization is to restore the binary stream into an object .

image-20230815151634862

Analogous to the transportation of some large items in our lives, we need to unpack and pack them during transportation, and then unpack and assemble them again when using them.

What is the use of Serializable interface?

This interface is just a mark and has no specific function. However, if this interface is not implemented, an error will be reported in some serialization scenarios. Therefore, it is generally recommended that all JavaBean classes created implement Serializable.

What is the use of serialVersionUID?

serialVersionUID is used for verification.

private static final long serialVersionUID = 1L;

We often see code like this. This ID is actually used to verify whether the serialized object and the corresponding object ID of the deserialization are consistent.

The number of this ID is actually not important, whether it is automatically generated by 1L or IDE, as long as the serialVersionUID of the object during serialization is consistent with the serialVersionUID of the object during deserialization.

If the serialVersionUID is not explicitly specified, the compiler will automatically generate one based on the relevant information of the class, which can be considered a fingerprint. So if you do not define a serialVersionUID, and after serializing an object, you change the class structure of the object before deserialization, such as adding a member variable, then the deserialization will fail at this time.

Because the structure of the class has changed, the serialVersionUID is inconsistent.

Java serialization does not include static variables?

Static variables are not included during serialization.

What if some variables don't want to be serialized?

For variables that do not want to be serialized, use transientkeyword modification.

transientThe function of keywords is:

  • Prevents the serialization of variables in the instance that are modified with this keyword;
  • When the object is deserialized, the transientmodified variable value will not be persisted and restored;
  • transientYou can only modify variables, not classes and methods.

46. ​​How many serialization methods are there?

There are many Java serialization methods, and there are three common ones:

image-20230815152157751

  • Java object serialization : Java native serialization method is to convert through Java native stream (conversion between InputStream and OutputStream), usually object output stream ObjectOutputStreamand object input stream ObjectInputStream.
  • Json serialization : This may be our most commonly used serialization method. There are many options for Json serialization. Generally, the jackson package is used to perform some operations through the ObjectMapper class, such as converting objects into byte arrays or converting json strings into objects. .
  • ProtoBuff serialization : ProtocolBuffer is a lightweight and efficient structured data storage format. ProtoBuff serialization objects can compress it to a large extent, which can greatly reduce the data transmission size and improve system performance.

Generics

47. Do you understand Java generics? What is type erasure? Introduce commonly used wildcards?

What are generics?

Java generics (generics) are a new feature introduced in JDK 5. Generics provide a compile-time type safety detection mechanism, which allows programmers to detect illegal types at compile time. The essence of generics is parameterized types, which means that the data type of the operation is specified as a parameter.

List<Integer> list = new ArrayList<>();

list.add(12);
//这里直接添加会报错
list.add("a");
Class<? extends List> clazz = list.getClass();
Method add = clazz.getDeclaredMethod("add", Object.class);
//但是通过反射添加,是可以的
add.invoke(list, "kl");

System.out.println(list); // 12 kl

Generics are generally used in three ways: generic classes, generic interfaces, and generic methods .

image-20230815153052292

1. Generic class:

//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{
    
    
    private T key;
    public Generic(T key) {
    
    
    	this.key = key;
    }
    
    public T getKey(){
    
    
    	return key;
    }
}

How to instantiate a generic:

Generic<Integer> genericInteger = new Generic<Integer>(123);

2. Generic interface:

public interface Generator<T> {
    
    
	public T method();
}

Implement the generic interface and specify the type:

class GeneratorImpl<T> implements Generator<String>{
    
    
    @Override
    public String method() {
    
    
    	return "hello";
    }
}

3. Generic methods:

public static < E > void printArray( E[] inputArray ){
    
    
    for ( E element : inputArray ){
    
    
    	System.out.printf( "%s ", element );
    }
    System.out.println();
}

use:

// 创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = {
    
     1, 2, 3 };
String[] stringArray = {
    
     "Hello", "World" };
printArray( intArray );
printArray( stringArray );

What are the commonly used wildcard characters for generics?

Commonly used wildcard characters are: T, E, K, V,?

  • ? Represents an undefined java type
  • T (type) represents a specific java type
  • KV (key value) respectively represents the Key Value in java key value
  • E (element) stands for Element

What is generic erasure?

The so-called generic erasure is officially called "type erasure".

Java's generics are pseudo-generics because all type information is erased during Java compilation.

In other words, there are no generics at runtime.

For example, this code puts a dog among a group of cats:

LinkedList<Cat> cats = new LinkedList<Cat>();
LinkedList list = cats; // 注意我在这里把范型去掉了,但是list和cats是同一个链表!
list.add(new Dog()); // 完全没问题!

Because Java's generics only exist in the source code, you can statically check whether the generic type is correct during compilation, but not at runtime. The above code looks no different from the following in JRE (Java Runtime Environment):

LinkedList cats = new LinkedList(); // 注意:没有范型!
LinkedList list = cats;
list.add(new Dog());

Why type erasure?

Mainly for backward compatibility, because there were no generics before JDK5. In order to keep the JVM backward compatible, the type erasure strategy was introduced.

annotation

48. Tell me about your understanding of annotations?

Java annotation is essentially a mark , which can be understood as some small outfits of a person in life, such as what hat or glasses to wear.

Annotations can be marked on classes, methods, attributes, etc. The mark itself can also set some values, such as the color of the hat is green.

After having the tags, we can identify these tags during the compilation or running phase, and then do something. This is the use of annotations.

For example, in our common AOP, using annotations as pointcuts is the application of runtime annotations ; for example, lombok is the application of annotations at compile time.

There are three major categories of annotation life cycles, namely:

  • RetentionPolicy.SOURCE: For the compiler, it will not be written to the class file.
  • RetentionPolicy.CLASS: Will be written to the class file and discarded during the class loading phase, that is, this information will not be available when running.
  • RetentionPolicy.RUNTIME: Will be written into the class file and saved permanently. Annotation information can be obtained through reflection.

So what I wrote above was about parsing, but I didn’t write about what exactly it was parsing, because the parsing actions in different life cycles are different.

Like the common ones:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override{
    
    
    
}

It is used by the compiler. When the compiler checks that there is no problem, it will be overridden. There will be no Override mark in the class file.

Another example is Spring's common Autowired, which is RUNTIME, so you can get the annotation information through reflection at runtime, and you can also get the value of the required tag.

image-20230815203123520

reflection

49. What is reflection? application? principle?

What is reflection?

We usually use the new method to create object instances, which can be said to be an "ortho". This method determines the type information at compile time. If, we want to dynamically obtain class information and create class instances at the time , When calling class methods, reflection is used.

Through reflection you can obtain all properties and methods of any class, and you can also call these methods and properties.

The four core categories of reflection:

image-20230815203307250

What are the application scenarios of reflection?

Generally, we are writing business code and rarely come into contact with scenarios where the reflection mechanism is directly used.

However, this does not mean that reflection is useless. On the contrary, it is reflection that allows you to use various frameworks so easily. Frameworks such as Spring/Spring Boot, MyBatis, etc. all use reflection mechanisms extensively.

Like many annotations in Spring, its real function is to use reflection.

Just like why when we use Spring, an @Componentannotation declares a class as a Spring Bean? @valueWhy can the value in the configuration file be read through an annotation? How exactly does it work?

These are all because we can operate the class based on reflection, and then obtain the annotations on the parameters of the class/attribute/method/method. Annotations have two functions here. One is to mark. We perform the annotation mark on the class/attribute/method. Corresponding processing; second, the annotation itself has some information that can participate in the processing logic.

The principle of reflection?

We all know that the execution of a Java program is divided into two steps: compilation and running. After compilation, a bytecode (.class) file will be generated. When the JVM loads a class, it will load the bytecode file and load all the information related to the type into In the method area , reflection is to obtain this information and then perform various operations .

JDK1.8 new features

50. What are the new features of JDK1.8?

JDK1.8 has many new features. The new features we often come into contact with are as follows:

image-20230815203848850

  • Interface default method: Java 8 allows us to add a non-abstract method implementation to the interface, just use the default keyword to modify it

  • Lambda expression and functional interface: Lambda expression is essentially an anonymous inner class, or it can be a piece of code that can be passed around.

    Lambda allows the function to be used as a parameter of a method (the function is passed to the method as a parameter). Use Lambda expressions to make the code more concise, but do not abuse it, otherwise there will be readability problems, Josh Bloch, author of "Effective Java" suggested It is best to use lambda expressions in no more than 3 lines.

  • Stream API: A tool that uses functional programming to perform complex operations on collection classes . It can be used with Lambda expressions to easily process collections.

    A key abstraction for working with collections in Java 8. It allows you to specify the operations you want to perform on collections, and can perform very complex operations such as finding, filtering, and mapping data. Using the Stream API to operate on collection data is similar to performing database queries using SQL. You can also use the Stream API to perform operations in parallel.

    In short, the Stream API provides an efficient and easy-to-use way to process data.

  • Date and time API: Java 8 introduces a new date and time API to improve date and time management.

  • Optional class: Used to solve the problem of null pointer exception. The Google Guava project introduced Optional a long time ago as a way to solve null pointer exceptions. It disapproved of code being polluted by null-checking code and expected programmers to write clean code. Inspired by Google Guava, Optional is now part of the Java 8 library.

51. How much do you know about Lambda expressions?

A lambda expression is essentially an anonymous inner class or a passable code.

For example, we used Runnable to create and run threads:

new Thread(new Runnable() {
    
    
    @Override
    public void run() {
    
    
    	System.out.println("Thread is running before Java8!");
    }
}).start();

This is to rewrite the run method through an inner class and use Lambda expressions, which can be more concise:

new Thread( () -> System.out.println("Thread is running since Java8!") ).start();

Of course not every interface can be abbreviated into a Lambda expression. Only those functional interfaces (Functional Interface) can be abbreviated into Lambda expressions.

The so-called functional interface (Functional Interface) is a declaration that contains only one abstract method . All lambda expressions for this interface type will match this abstract method.

What built-in functional interfaces does Java8 have?

The JDK 1.8 API includes many built-in functional interfaces. These include Comparator and Runnable that we often see in older versions . Java 8 adds @Functionallnterface annotations to them to support Lambda expressions.

In addition to these two, there are Callable, Predicate, Function, Supplier, Consumer and so on.

52. Do you understand Optional?

OptionalIt is for prevention NullPointerException.

Think Optionalof it as a container that wraps objects (which may or nullmay not be objects null). When we define a method and the object returned by this method may be empty or non-empty, we can optionalconsider wrapping it. This is also a recommended approach in Java 8.

Optional<String> optional = Optional.of("bam");

optional.isPresent(); // true
optional.get(); // "bam"
optional.orElse("fallback"); // "bam"

optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "b"

53. Have you ever used Stream?

image-20230815205622664

StreamStreams, simply put, are used to java.util.Streamperform various operations on a collection containing one or more elements. These operations may be intermediate operations or terminal operations . Terminal operations return a result, while intermediate operations return a Streamstream.

StreamStreams are generally used for collections. We perform several common operations on a collection:

List<String> stringCollection = new ArrayList<>();
stringCollection.add("ddd2");
stringCollection.add("aaa2");
stringCollection.add("bbb1");
stringCollection.add("aaa1");
stringCollection.add("bbb3");
stringCollection.add("ccc");
stringCollection.add("bbb2");
stringCollection.add("ddd1");
  • Filter filter
stringCollection
    .stream()
    .filter((s) -> s.startsWith("a"))
    .forEach(System.out::println);
// "aaa2", "aaa1"
  • Sorted Sorted
stringCollection
    .stream()
    .sorted()
    .filter((s) -> s.startsWith("a"))
    .forEach(System.out::println);
// "aaa1", "aaa2"
  • Map conversion
stringCollection
    .stream()
    .map(String::toUpperCase)
    .sorted((a, b) -> b.compareTo(a))
    .forEach(System.out::println);
// "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"
  • Match match
// 验证 list 中 string 是否有以 a 开头的, 匹配到第一个,即返回 true
boolean anyStartsWithA =
    stringCollection
        .stream()
        .anyMatch((s) -> s.startsWith("a"));
System.out.println(anyStartsWithA); // true

// 验证 list 中 string 是否都是以 a 开头的
boolean allStartsWithA =
    stringCollection
        .stream()
        .allMatch((s) -> s.startsWith("a"));
System.out.println(allStartsWithA); // false

// 验证 list 中 string 是否都不不是以 z 开头的,
boolean noneStartsWithZ =
    stringCollection
        .stream()
        .noneMatch((s) -> s.startsWith("z"));
System.out.println(noneStartsWithZ); // true
  • Count count

countIt is a terminal operation that can count stream the total number of elements in the stream, and the return value is long the type.

// 先对 list 中字符串串开头为 b 进⾏行行过滤,让后统计数量量
long startsWithB =
    stringCollection
        .stream()
        .filter((s) -> s.startsWith("b"))
        .count();
System.out.println(startsWithB); // 3
  • Reduce

ReduceChinese translation: reduce, shrink. By entering parameters Function, we can reduce the list to a value. Its return type is Optional type.

Optional<String> reduced =
    stringCollection
        .stream()
        .sorted()
        .reduce((s1, s2) -> s1 + "#" + s2);
reduced.ifPresent(System.out::println);
// "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"

The above are several common streaming operations, and there are other streaming operations that can help us process collection data more conveniently.

Reprint address: Counterattack of noodle scum: Fifty-three questions on Java basics, come and see if there is anything you don’t know! (qq.com)

Guess you like

Origin blog.csdn.net/weixin_45483322/article/details/132307130