Java review notes

Posted by sujithfem on Wed, 02 Feb 2022 14:17:58 +0100

Chapter 1 overview of Java

1.1 Java history

Java was born in SUN (Stanford University Network), which was acquired by Oracle (Oracle) in 2009.

The father of Java is James James gosling.

JDK1.0 was released in 1996 Version 0.

The latest version is java 12. We learned Java 8.

1.2 main features of Java language

  • Feature 1: object oriented

Two basic concepts: class and object

Three characteristics: encapsulation, inheritance and polymorphism

  • Feature 2: robustness

It absorbs the advantages of C/C + + language, but removes the parts that affect the robustness of the program (such as pointer, memory application and release, etc.), and provides a relatively safe memory management and access mechanism

  • Feature 3: cross platform

Cross platform: applications written in Java language can run on different system platforms. Write once, run anywhere.

Principle: just install a Java virtual machine (JVM) on the operating system that needs to run Java applications. The JVM is responsible for the running of Java programs in the system. Because of the JVM, the same Java program can be executed in three different operating systems. In this way, the cross platform of Java program is realized.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-IyUf5Wqa-1623826110052)(D:/atguigu/javaee/JavaSE20190503/note/imgs/1557828366412.png)]

1.3 Java environment construction

1.3.1 JDK,JRE,JVM

Java developers need to install JDK. If you just run a java program, you only need to follow the JRE.

JDK (Java Development kits): Java development kit.

JRE (Java Runtime Environment): Java Runtime Environment.

JVM (Java Virtual Machine): Java Virtual Machine.

JDK = JRE + development tools (javac.exe,java.exe,javadoc.exe, etc.)

JRE = JVM + core class library (common classes: String, date and time, mathematics, set, IO, network, multithreading, etc.)

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-AO2cHdM9-1623826110054)(D:/atguigu/javaee/JavaSE20190503/note/imgs/1553593811117.png)]

1.3.2 Java environment construction

1. Install JDK

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-K2l4IBpw-1623826110056)(D:/atguigu/javaee/JavaSE20190503/note/imgs/1553644600381.png)]

2. Configure the JDK development tool directory to the path environment variable

For example: D: \ program files \ Java \ jdk1 8.0_ 51\bin;

Note: this installation directory is subject to your own installation directory

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-equifk5b-1623826110058) (D: / atguigu / JavaEE / javase20190503 / Note / IMGs / 1553644724825. PNG)]

(1) Why configure path?

You want to use javac. Net on the command line Exe and other tools, the directory where this tool is located can be found in any directory.

(2) How to configure environment variables?

[Computer] right click [properties], select [advanced system settings], select [advanced], select [environment variable], select [system environment variable], edit path, and add D: \ program files \ Java \ jdk1 before [original value of path] 8.0_ 51\bin;

1.4 first Java application

class HelloWorld{
    public static void main(String[] args){
        System.out.print("Hello Java!");
    }
}

1.4.1 development steps of Java program

Three steps:

1. Edit / write source code

Requirement: the source file must be java file

2. Compile

Purpose: to compile the source file into class bytecode file (because the JVM only knows bytecode)

Tool: javac exe

Format:

javac Source file name.java

3. Run

Tool: Java exe

Format:

java Class name
java Bytecode file name

Requirement: the class that can be run must contain the main method

1.4.2 structure and format of Java program

Structure:

class{
    method{
        sentence;
    }
}

Format:

(1) Indent one Tab at each level

(2) The left half of {} is at the end of the line, and the right half is a separate line, aligned with the beginning of the line of "{" paired with it

1.4.3 Java program entry

The entry of Java program is the main method

public static void main(String[] args){
    
}

1.4.4 Java annotation

1. Single line note

//Note Content 

2. Multiline comment

/*
Note Content 
*/

3. Document notes

/**
Document notes (explained in the notes section later)
*/

1.5 problems that should be paid attention to when writing Java programs

1. Character encoding problem

When the character encoding of cmd command line window is the same as The character encoding of java source file is inconsistent. How to solve it?

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-yN0gSEHs-1623826110060)(imgs/1557881223916.png)]

Solution 1:

In Notepad + + and other editors, modify the character encoding of the source file

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-MQYkBw6O-1623826110061)(imgs/1557881271819.png)]

Solution 2:

When using javac imperative, you can specify the character encoding of the source file

javac -encoding utf-8 Review01.java

2. Case problem

(1) Source file name:

It is not case sensitive. We suggest that you still distinguish between cases

(2) Bytecode file name and class name

Case sensitive

(3) In code

Case sensitive

3. Is the source file name consistent with the class name?

(1) Must the source file name be consistent with the class name? What about public?

If this class is not public, the source file name can be inconsistent with the class name.

If this class is public, the source file name must be consistent with the class name.

We recommend that you keep the name of the source file consistent with whether it is public or not, and try to write only one class in a source file for easy maintenance.

(2) Can there be multiple classes in a source file? What about public?

There can be multiple classes in a source file, which will be generated after compilation class bytecode file.

However, a source file can only have one public class.

(3) Must main be in the public class?

no

However, when writing code later, basically main is used to being in the public class.

Chapter 2 basic syntax of Java

2.1 identifier

In short, any part named by the programmer can be called an identifier.

That is, the character sequence named for class, variable, method, package, etc. is called identifier.

1. Naming rules for identifiers

(1) Java identifiers can only use 26 English letters, uppercase and lowercase, numbers 0-9, underscores, Dollar sign$

(2) Java keywords (including reserved words) and special values cannot be used

(3) Number cannot start

(4) Cannot contain spaces

(5) Strictly case sensitive

2. Naming conventions for identifiers

(1) See the name and know the meaning

(2) Class name, interface name, etc.: the first letter of each word is capitalized in the form of xxxyyyzz,

For example: HelloWorld, String, System, etc

(3) Variable, method name, etc.: start with the first letter of the second word in uppercase and the rest in lowercase. Form: xxxyyyzz,

For example: age,name,bookName,main

(4) Package name, etc.: each word is lowercase, and points are used between words Division, form: XXX yyy. zzz,

For example: Java lang

(5) Constant name, etc.: each word is capitalized and underlined between words_ Division, form: XXX_YYY_ZZZ,

For example: MAX_VALUE,PI

2.2 variables

2.2.1 concept of variable

Function of variable: it is used to store data and represents a storage area of memory. The value in the variable can be changed.

2.2.2 three elements of variables

1. Data type

2. Variable name

3. Value

2.2.3 what should we pay attention to when using variables?

1. Declaration before use

If there is no declaration, an error of "symbol not found" will be reported

2. Must be initialized before use

If it is not initialized, an "uninitialized" error will be reported

3. Variable has scope

If the scope is exceeded, the error "symbol not found" will also be reported

4. Cannot duplicate names in the same scope

2.2.4 declaration and assignment of variables, syntax format used?

1. Syntax format of variable declaration:

Data type variable name;
For example:
int age;
String name;
double weight;
char gender;
boolean isMarry;

2. Syntax format of variable assignment:

Variable name = value;
For example:
age = 18;
name = "Chai Linyan"; //The value of the string must use ''
weight = 44.4;
gender = 'female';//Single character values must use ''
isMarry = true;

3. Syntax format of variable:

Direct reference by variable name

For example:
(1)Value of output variable
System.out.print(name);
System.out.print("full name:" + name);//The contents of "" will be displayed as is
System.out.print("name = " + name);
(2)calculation
age = age + 1;

2.3 data type

2.3.1 classification of Java data types

1. Basic data type

8 types: integer series (byte,short,int,long), floating point (float,double), single character (char), boolean (boolean)

2. Reference data type

Class, interface, array, enumeration

2.3.2 basic data types of Java

1. Integer series

(1) Byte: byte type

Memory occupied: 1 byte

Storage range: - 128 ~ 127

(2) Short: short integer type

Memory occupied: 2 bytes

Storage range: - 32768 ~ 32767

(3) int: integer

Memory: 4 bytes

Storage range: - 31st power of 2 ~ 31st power of 2 - 1

(4) long: integer

Memory occupied: 8 bytes

Storage range: - 63rd power of 2 ~ 63rd power of 2 - 1

Note: if you want to represent a constant number, which is of type long, you need to add L after the number

2. Floating point series (decimal)

(1) float: single precision floating point

Memory: 4 bytes

Accuracy: 6 ~ 7 digits after the decimal point of scientific notation

Note: if you want to indicate that a constant number is of float type, you need to add f or F after the number

(2) Double: double precision floating point type

Memory occupied: 8 bytes

Accuracy: 15 ~ 16 digits after the decimal point of scientific notation

3. Single character type

char: character type

Memory occupied: 2 bytes

Character set used in Java: Unicode encoding set

Three representations of characters:

(1) 'one character'

For example: 'A', '0', 'not yet'

(2) Escape character

\n: Line feed
\r: enter
\t: Tab key
\\: \
\": "
\': 
\b: Delete key Backspace

(3) The hexadecimal type of the Unicode encoded value of the \ u character

For example: \ u5c1a stands for 'still'

4. Boolean type

boolean: only true or false can be stored

2.3.3 hexadecimal (understand, can be ignored temporarily)

1. Binary classification:

(1) Decimal system

Digital composition: 0-9

Carry rule: every decimal

(2) Binary

Digital composition: 0-1

Carry rule: every two into one

(3) Octal

Digital composition: 0-7

Carry rule: one for every eight

(4) Hex

Digital composition: 0-9, AF (or AF)

Carry rule: one every 16

2. Please use four types of hexadecimal to represent 10, and output its results: (understand)

(1) Decimal: normal representation

System.out.println(10);

(2) Binary: beginning with 0b or 0b

System.out.println(0B10);

(3) Octal: beginning with 0

System.out.println(010);

(4) Hex: starting with 0x or 0x

System.out.println(0X10);

3. Why is byte - 128 ~ 127? (understanding)

1 byte: 8 bits

0000 0001 ~ 0111 111 ==> 1~127

1000 0001 ~ 1111 1111 ==> -127 ~ -1

0000 0000 ==>0

1000 0000 = = > - 128 (special provisions)

*Explanation: * storage of computer data (understand)

Computer data is stored in the form of binary complement, and the highest bit is symbol bit, 1 is negative and 0 is positive.

Regulations: the complement of positive numbers is the same as the inverse code and the original code, which is called three in one;

The complement of a negative number is different from the inverse code and the original code:

Original code of negative number: convert decimal to binary, and then set the highest bit to 1

Inverse code of negative numbers: on the basis of the original code, the highest bit remains unchanged, and the other bits are reversed (0 becomes 1, 1 becomes 0)

Complement of negative number: inverse code + 1

For example: byte type (1 byte, 8 bits)

25 = = > original code 0001 1001 = = > inverse code 0001 1001 -- > complement code 0001 1001

-25 = = > original code 1001 1001 = = > inverse code 1110 0110 = = > complement code 1110 0111

The bottom layer uses addition instead of subtraction: - 128 = = "- 127-1 = =" - 127 + (- 1)

​ -127- -1 ==> -127 + 1

4. Student questions and answers?

(1) Why is the storage range of float (4 bytes) larger than that of long (8 bytes)?

(2) Why is double (8 bytes) more accurate than float (4 bytes)?

Because the bottom layer of float and double is also binary, first convert the decimal to binary, then express the binary as scientific notation, and then save only:

(1) Sign bit (2) index bit (3) trailing digit

For details, see "storage method of float and double data. docx"

2.3.4 conversion of basic data types

1. Automatic type conversion

(1) When a value with a small storage range (constant value, variable value, result value of expression calculation) is assigned to a variable with a large storage range,

byte->short->int->long->float->double

​ char->

int i = 'A';//char is automatically upgraded to int
double d = 10;//int is automatically upgraded to double

(2) When a data type with a small storage range is mixed with a data type with a large storage range, it will be calculated according to the largest type

int i = 1;
byte b = 1;
double d = 1.0;

double sum = i + b + d;//Mixed operation, upgrade to double

(3) When the byte, short and char data types perform arithmetic operations, they are processed according to the int type

byte b1 = 1;
byte b2 = 2;
byte b3 = (byte)(b1 + b2);//b1 + b2 is automatically upgraded to int

char c1 = '0';
char c2 = 'A';
System.out.println(c1 + c2);//113 

(4) boolean type does not participate

2. Cast type

(1) When a value with a large storage range (constant value, variable value, result value of expression calculation) is assigned to a variable with a small storage range, forced type conversion is required

double->float->long->int->short->byte

​ ->char

Tip: there is a risk of loss of accuracy or overflow

double d = 1.2;
int num = (int)d;//Loss accuracy

int i = 200;
byte b = (byte)i;//overflow

(2) boolean type does not participate

(3) Cast can also be used when a value wants to promote the data type

int i = 1;
int j = 2;
double shang = (double)i/j;

Tip: there is no risk of cast in this case.

2.3.5 special data type conversion

1. When "+" operation is performed between any data type and String type, the result must be String type

System.out.println("" + 1 + 2);//12

2. However, String type cannot be converted to other types through forced type ()

String str = "123";
int num = (int)str;//FALSE

2.4 operators

1. Classification by operands:

(1) Unary operator: there is only one operand

For example: positive sign (+), negative sign (-), self increasing (+ +), self decreasing (–), logical non (!), Bitwise inversion (~)

(2) Binary operator: there are two operands

For example: add (+), subtract (-), multiply (*), divide (/), modulus (%)

Greater than (>), less than (<), greater than or equal to (> =), less than or equal to (< =), equal to (= =), not equal to (! =)

Assignment (=, + =, - =, * =, / =,% =, > > =, < < =.)

Logical and (&), logical or (|), logical XOR (^), short circuit and (& &), short circuit or (|)

Shift left (< >), shift right (> >), unsigned shift right (> >), bitwise and (&), bitwise OR (|), bitwise XOR (^)

(3) Ternary operator: three operands

For example:?:

2. Operators of Java basic data types:

(1) Arithmetic operator

(2) Assignment operator

(3) Comparison operator

(4) Logical operator

(5) Conditional operator

(6) Bitwise operator (difficult)

2.4.1 arithmetic operators

Addition:+

Subtraction:-

Multiplication:*

Division:/

Note: the integer is divided by the integer, and only the integer part is reserved

Mold taking:% remainder

Note: the sign of the modulus result only depends on the modulus

Positive sign:+

Minus sign:-

Self increment:++

Self subtraction: –

Principle: self increase and self decrease

++/– the first one is self increasing / self decreasing, and then the value is taken

++/– in the latter, take the value first, and then increase / decrease automatically

The whole expression is scanned from left to right. If the latter is calculated first, the former will be put into the "operand stack" temporarily

Code example:

int i = 1;
i++;//i=2

int j = 1;
++j;//j=2

int a = 1;
int b = a++;//(1) First take the value "1" of a and put it on the operand stack (2), a will increase automatically, a=2(3), and then assign "1" in the operand stack to b,b=1

int m = 1;
int n = ++m;//(1)m increases automatically first, m=2(2), then take the value "2" of m and put it on the operand stack (3), and then assign "2" in the operand stack to n,n=1

int i = 1;
int j = i++ + ++i * i++;
/*
Load from left to right
(1)First calculate i++
①Take the value "1" of i and put it on the operand stack
②i Self increasing i=2
(2)Recalculate + + i
①i First self increasing i=3
②Then take the value "3" of i and put it on the operand stack
(3)Recalculate i++
①Take the value "3" of i and put it on the operand stack
②i Self increasing i=4
(4)Multiply first
 Use 3 * 3 = 9 in the operand stack and press 9 into the operand stack
(5)Recalculate and sum
 Use 1 + 9 = 10 in the operand stack
(6)Final assignment
j = 10
*/

2.4.2 assignment operator

Basic assignment operator:=

Extended assignment operators: + =, - =, * =, / =,% =

Note: the = left side of all assignment operators must be a variable

Extended assignment operator = if the type of the calculation result on the right is larger than that on the left, the type conversion will be forced, so the result may be at risk.

Calculation of extended assignment operator: (1) the last calculation of assignment (2) the order of loading data is to load the value of the variable on the left first, and then calculate it with the expression on the right

int i = 1;
int j = 5;
j *= i++ + j++;//j = j *(i++ + j++);
/*
(1)Load j's value "5" first
(2)In calculating i++
①Load the value "1" of i first
②Then i increases automatically, i=2
(3)Recalculate j++
①Load j's value "5" first
②Then J increases automatically, j=6
(4)Calculate addition
i + 5 = 6
(5)Calculate multiplication
5 * 6 = 30
(6)assignment
j = 30
*/

2.4.3 comparison operator

Greater than: >

Less than:<

Greater than or equal to: >=

Less than or equal to:<=

Equal to: = = pay attention to the difference between assignment operators=

Not equal to:=

Note: the operation result of the comparison expression must only be true/false

Comparison expressions can be used as operands of (1) conditional (2) logical operators

2.4.4 logical operators

The operand of a logical operator must be Boolean and the result is also Boolean

Logic and:&
Operation rule: the result is true only if both sides are true.
For example: true & true, the result is true
False & true the result is false
True & false the result is false
False & false the result is false
Logical or:|
Operation rule: as long as one of the left and right sides is true, the result is true.
For example: true | true, the result is true
false | true the result is true
true | false the result is true
false | false the result is false
Logical XOR:^
Operation rule: the result is true only when the left and right sides are different.
For example: true ^ true, the result is false
false ^ true the result is true
true ^ false the result is true
false ^ false the result is false

Logical non:!
Operation rule: Boolean negation
For example:! true is false
! false is true

Short circuit and:&&
Operation rule: the result is true only if both sides are true.
For example: true & true, the result is true
True & false the result is false
false & ? The result is false
The difference between it and logic is that when && the left is false, the right will not be seen.

Short circuit or:||
Operation rule: as long as one of the left and right sides is true, the result is true.
For example: true? The result is treu
false | true the result is true
false | false the result is false
The difference between it and logic or is that when the left is true, the right is not seen.

Short circuit and and short circuit are generally used in development or more

Interview question: & & and &?

&&When the left is false, the right is not calculated

&Whether the left side is true or false, the right side should be calculated

2.4.5 conditional operators

? :

Syntax format:

Conditional expression ? Result expression 1 : Result expression 2

Operation rules:

Result of the whole expression: when the conditional expression is true, the value of result expression 1 is taken; otherwise, the value of result expression 2 is taken

Code example:

(1)boolean type
boolean marry = true;
System.out.println(marry? "married" : "unmarried");

(2)Find the most value
int i = 3;
int j = 5;
int max = i>=j ? i : j;
//When i > = j, max is assigned the value of i, otherwise it is assigned the value of j

2.4.6 bitwise operators

Move left:<<

Operation rule: a few bits to the left is equivalent to multiplying by 2

Shift right: > >

Operation rule: shifting a few bits to the right is equivalent to dividing by the power of 2

Unsigned right shift: > > >

Operation rule: after moving to the right, the empty bits on the left will be directly filled with 0 without looking at the symbol bits

Bitwise AND:&

Operation rules:

1 & 1 result is 1

1 & 0 result is 0

0 & 1 result is 0

0 & 0 results in 0

Bitwise OR:|

Operation rules:

1 | 1 the result is 1

1 | 0 result is 1

0 | 1 result is 1

0 & 0 results in 0

Bitwise exclusive or:^

Operation rules:

1 ^ 1 result is 0

1 ^ 0 result is 1

0 ^ 1 result is 1

0 ^ 0 results in 0

Bitwise inversion:~

Operation rule: ~ 0 is 1

~ 1 is 0

How to distinguish whether &, |, ^ is a logical operator or a bitwise operator?

If the operand is of boolean type, it is a logical operator. If the operand is an integer, it is a logical operator.

2.4.7 operator priority

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-S2NbUW8P-1623826110063)(imgs/1553858424335.png)]

Prompt Description:

(1) The expression should not be too complex

(2) Use of first count ()

2.4.8 operator operand type description

1. Arithmetic operator

Arithmetic operators can be used for numbers and single characters.

Where +, when used for string, indicates splicing.

2. Assignment operator

The type of constant value, expression value and variable value on the right must be consistent or compatible with the variable on the left (automatic type conversion can be realized) or forced type conversion can be successful.

3. Comparison operator

Other comparison operators can only be used for 8 basic data types.

Where = = and= It can be used for the comparison of reference data types and the address of comparison objects. (later)

int i = 10;
int j = 10;
System.out.println(i==j);//true

char c1 = 'Handsome';
char c2 = 'Handsome';
System.out.println(c1 == c2);//true

4. Logical operator

The operand of a logical operator must be a boolean value

5. Conditional operator

? The preceding must be a condition and a boolean value

Result expression 1 and result expression 2 should be of the same type or compatible

6. Bitwise operator

Generally used for integer series

The above operators are designed for basic data types.

Only the basic assignment operator =, and the comparison operator = = and! =, can be used to reference data types. No other operators can be used to reference data types.

The string type also has a +, indicating splicing.

Chapter III structure of flow control statement

The structure of process control statement is divided into:

1. Sequential structure: execute from top to bottom

2. Branch structure: select one of multiple branches to execute

3. Loop structure: execute some code repeatedly

3.1 sequence structure

Execution process: from top to bottom

3.1.1 output statement

1,System. out. Print (output content)# No line break after output

2,System. out. Println (output content)# Wrap after output

#Output constant
System.out.print(1);
System.out.print('still');
System.out.print(44.4);
System.out.print(true);
System.out.print("Shang Silicon Valley");

#Output variable
int a = 1;
char c = 'still';
double d = 44.4;
boolean b = true;
String school = "Shang Silicon Valley";
System.out.print(a);
System.out.print(c);
System.out.print(d);
System.out.print(b);
System.out.print(school);

#Output splicing results
System.out.print("a = " + a);
System.out.print("c = " + c);
System.out.print("d = " + d);
System.out.print("b = " + b);
System.out.print("school = " + school);

3.1.2 input statement

There are three steps for entering codes on the keyboard:

1. Prepare variables of Scanner type

2. Prompt for xx

3. Receive input

Example code:

//1. Prepare variables of Scanner type
java.util.Scanner input = new java.util.Scanner(System.in);//System.in represents keyboard input by default

//2. Prompt for xx
System.out.print("Please enter an integer:");

//3. Receive input
int num = input.nextInt();

//Lists the inputs for various data types
int num = input.nextInt();
long bigNum = input.nextLong();
double d = input.nextDouble();
boolean b = input.nextBoolean();
String s = input.next();
char c = input.next().charAt(0);//First receive according to the string, and then take the first character of the string (subscript 0)

3.2 branch structure

Branch structure: selectively execute some code according to conditions

Divided into:

1. Conditional judgment: if... else series

2. Select structure: switch... case series

3.2.1 condition judgment

1. Single branch structure

Syntax format:

if(Conditional expression){
    When the conditional expression holds(true)Block of statements to execute when;
}

Execution process:

If the condition is true, execute {} the statement block in it. If it is not true, do not execute it.

be careful:

(1) The result of a conditional expression in if (conditional expression) must be of type boolean

(2) When the statement in {} has only one statement (a simple statement or a compound statement), you can omit {}, but we do not recommend omitting it

		//Omitting {}
		if(score<0 || score>100)
			System.out.println("Wrong input!");//Simple statement
		else
			//Compound statement
			if(score==100){
				System.out.println("Full mark");
			}else if(score>=80){
				System.out.println("excellent");
			}else if(score>=60){
				System.out.println("pass");
			}else{
				System.out.println("fail,");
			}

Example code:

int year = 2019;
int days = 28;
if(year%4==0 && year%100!=0 || year%400==0){
    days= 29;
}

2. Double branch structure

Syntax format:

if(Conditional expression){
    When the conditional expression holds(true)Statement block 1 to be executed at;
}else{
    When the conditional expression does not hold(false)Statement block 2 to be executed when;
}

Execution process:

When the conditional expression is true, execute statement block 1, otherwise execute statement block 2

be careful:

(1) The result of a conditional expression in if (conditional expression) must be of type boolean

(2) When the statement in {} has only one statement (simple statement or compound statement), you can omit {}, but we don't recommend it

Example code:

int num = 10;
if(num%2==0){
    System.out.println(num + "It's an even number");
}else{
     System.out.println(num + "It's an odd number");
}

3. Multi branch structure

Syntax format:

if(Conditional expression 1){
    When the conditional expression 1 is true, the executed statement block 1;
}else if(Conditional expression 2){
    When conditional expression 1 does not hold,
      When conditional expression 2 is true, execute statement block 2;
}else if(Conditional expression 3){
    When conditional expression 1 does not hold,
       Conditional expression 2 does not hold,
      When conditional expression 3 is true, execute statement block 3;
}
. . . 
[else{
	When all the above conditional expressions are not true, the statement block to be executed n+1;
}]

Execution process:

(1) Multiple conditions are judged in sequence. If one of the above conditions is true, the following conditions will not be viewed

(2) Multiple branches will execute only one of them

be careful:

(1) Every conditional expression must be a boolean value

(2) When there is only one statement in {}, {} can also be omitted, but it is not recommended to omit

(3) When multiple conditions are mutually exclusive (no overlap), the order can be arbitrary;

When multiple conditions are "inclusive" (with overlapping parts), the order cannot be arbitrary. The small one is above and the large one is below

Example code:

			int score = 78;
			if(score==100){
				System.out.println("Full mark");
			}else if(score>=80){
				System.out.println("excellent");
			}else if(score>=60){
				System.out.println("pass");
			}else{
				System.out.println("fail,");
			}

4. Nesting

Execution process:

When it is nested in if, that is, when the external if is true, it will look at the internal condition judgment;

When nested in else, only when the external else is satisfied will the inner condition be judged;

3.2.2 structure selection

Syntax format:

switch(expression){
    case Constant value 1:
        Statement block 1;
        [break;]
    case Constant value 2:
        Statement block 2;
        [break;]   
    . . . 
   [default:
        Statement block n+1;
        [break;]
     ]
}

Execution process:

(1) Entrance

① When the value of switch (expression) matches a constant value after case, it enters from this case;

② When the value of switch (expression) does not match all constant values after case, look for the default branch to enter;

(2) Once you enter the switch from the "entrance", it will be executed in sequence until you encounter the "exit"

(3) Export

① Natural exit: encountered the end of switch}

② Interrupt exit: encountered break, etc

be careful:

(1) The value type of switch (expression) can only be four basic data types (byte,short,int,char) and two reference data types (enumeration, String)

(2) case must be followed by a constant value and cannot be repeated

Example code:

int month = 4;
switch(month){
    case 3:
    case 4:
    case 5:
        System.out.println("spring");
        break;
    case 6:
    case 7:
    case 8:
        System.out.println("summer");
        break;
    case 9:
    case 10:
    case 11:
        System.out.println("autumn");
        break;
    case 12:
    case 1:
    case 2:
        System.out.println("winter");
        break;
    default:
        System.out.println("Wrong input!");
}

3.3 circulation structure

Cycle structure:

"Duplicate" execution of some code

Classification of cyclic structure:

1. for loop

2. while loop

3. do... while loop

3.3.1 for loop

Syntax format:

for(;;){
    Circular aspect sentence block;
    if(Conditional expression){
    	break;
    }
}
for(Initialization expression; Cycle condition; Iterative expression){
    Circular aspect sentence block; (code that needs to be executed repeatedly)
}

Execution process:

(1) Initialization expression;

(2) Judge the cycle conditions;

(3) If the circular condition is true, execute the circular body sentence block first; Then execute the iterated expression and return to (2)

(4) If the cycle condition does not hold, it will end for;

Or if a break statement is encountered in the current loop, the current for loop will also be ended;

be careful:

(1)for(;;) Two of the; It can't be more or less

(2) Loop condition must be of type boolean

Example code:

//Traverse even numbers between 1-100
for(int i=1; i<=100; i++){//The stride of each cycle is 1
    if(i%2==0){
        System.out.println(i);
    }
}

//Traverse even numbers between 1-100
for(int i=2; i<=100; i+=2){//The stride of each cycle is 2
    System.out.println(i);
}

3.3.2 while loop

Syntax format:

while(Cycle condition){
    Circular aspect sentence block;
}

Classic form:
while(true){
	Circular aspect sentence block;
    if(Conditional expression){
    	break;
    }
}

Execution process:

(1) Judge the cycle condition first

(2) If the circular condition is true, execute the circular body sentence block; Then go back to (1)

(3) If the loop condition is not true, end the while loop;

If a break is encountered in the loop style sentence block, the while loop will also be ended;

be careful:

(1) Loop condition in while must be of type boolean

Example code:

//Traverse even numbers between 1-100
int num = 2;
while(num<=100){
    System.out.println(num);
    num+=2;
}

3.3.3 do... while loop

Syntax format:

do{
    Circular aspect sentence block;
}while(Cycle condition);

Execution process:

(1) First execute a circular body sentence block;

(2) Judge cycle conditions

(3) If the loop condition holds, execute the loop body sentence block again; Then go back to (2)

(4) If the loop condition does not hold, end the do... while loop;

If you encounter a break in the loop style sentence block, you will also end the do... while loop;

be careful:

(1) Loop condition in while must be of type boolean

(2)do{}while(); There is a semicolon at the end

(3) The circular body sentence of do... While structure will be executed at least once, which is different from that of for and while

Example code:

//Enter an integer from the keyboard, count the number of positive and negative numbers, and enter 0 to end
java.util.Scanner input = new java.util.Scanner(System.in);

int num;
int positive = 0;
int negative = 0;
do{
    System.out.print("Please enter an integer (ending with 0):");
    num = input.nextInt();
    
    if(num > 0){
        positive++;
    }else if(num < 0){
        negatvie++;
    }
}while(num!=0);

System.out.println("Number of positive numbers:" + positive);
System.out.println("Number of negative numbers:" + negatvie);

3.3.4 selection of three cycles

Principle: the three cycles can be converted to each other, and all of them can realize the function of cycle

Suggestion (habitually): when the number of times is obvious, or from several cycles to several, we generally consider for first;

When a circular body sentence block needs to be executed at least once, it is generally considered to do... while first;

When the loop condition is obvious, but the number of times is not obvious, and the loop body sentence block is not executed at least once, the while structure can be considered;

The three cycle structures have four elements:

(1) Initialization expression of loop variable

(2) Cycle condition

(3) Modified iterative expression of cyclic variable

(4) Circular aspect sentence block

3.3.5 jump statement

1,break

be used for:

(1) switch structure

Function: end switch structure

(2) Cyclic structure

Function: end the current cycle

2,continue

be used for:

Can only be used for circular structures

Function: end this cycle in advance and continue the next cycle

3. return (later)

Chapter 4 array

4.1 array related concepts and nouns (understand)

1. Array:

A set of data with the same data type arranged in a certain order.

Use one name to manage a limited number of variables of the same type.

2. Array name:

(1) this array name represents a group of numbers

(2) "first address" of the entire array stored in this array name

3. Index:

We use number, index and subscript to distinguish one of a group of numbers.

Range: [0, array length - 1]

For example: for (int i = 0; I < arr.length; I + +) {}

4. Element:

Every data in this group is an element.

How to represent array elements? Array name [subscript]

5. Length of array

The total number of elements in the array.

How to get the array length? Array name length

Note: the name is for the convenience of communication, and the concept does not need to be memorized without a word

4.2 array related syntax

4.2.1 declaration of array

Syntax format:

 //recommend
 Data type of element[] Array name;

 //Yes, but not recommended
 The data type array name of the element[];

Example:

//To store a set of integers
int[] array;

//To store a set of single characters
char[] array;

//To store a set of strings
String[] array;

4.2.2 initialization of array

The purpose of initialization: (1) determine the length of the array (2) assign a value to the element

There are two initialization methods:

1. Dynamic initialization

Syntax format:

//Specify array length
 Array name = new Data type of element[length];

//Assign values to elements
 Array name[subscript] = value; //This value can be a constant value, the calculation result of an expression, or keyboard input

//If the assignment of each element is regular, the for loop assignment is usually used
for(int i=0; i<length; i++){
    Array name[subscript] = value;
}

Q: if you only specify the length of the array and do not assign a value to the element manually, does the element have a value?

There are default values

(1) Basic data type

​ byte,short,int,long: 0

​ float,double: 0.0

​ char: \u0000

​ boolean: false

(2) Reference data type

It's all null

2. Static initialization

Syntax format:

Array name = new Data type of element[]{Value list};

//int[] arr = new int[5]{1,2,3,4,5};// FALSE

//More concise
//When the declaration is completed with static initialization, it can be simplified
 Data type of element[] Array name = {Value list};

Applicable occasions:

Static initialization can be used when the elements of an array are known to be finite.

Example code:

String[] weeks = {"monday","tuesday","wednesday","thursday","friday","saturday","sunday"};

int[] daysOfMonths = {31,28,31,30,31,30,31,31,30,31,30,31};

char[] letters = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

4.2.3 traversal of array

for loop traversal array:

for(int i=0; i<Array name.lenght; i++){
    //Or assignment
    Array name[i] = value;
    //Or display
    System.out.println(Array name[i]);
    //Or other operations
    //For example: judge whether it is an even number
    if(Array name[i]%2==0){
          //...
    }
}

4.2.4 memory analysis of array

Element is a one-dimensional array memory analysis of basic data type:

int[] arr = {1,2,3,4,5};

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG gdyfcsyq-1623826110066) (IMGs / 1558400311779. PNG)]

int[] arr = new int[5];
for(int i=0; i<arr.length; i++){
    arr[i] = i+1;
}

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-LNvBREj5-1623826110066)(imgs/1558400323314.png)]

4.3 array related algorithms

4.3.1 array find the most value

1. Find the latest value in the array

Idea:

(1) First assume the first element is Max / min

(2) Then compare max/min with the following elements one by one

Example code:

int[] arr = {4,5,6,1,9};
//Find maximum value
int max = arr[0];
for(int i=1; i<arr.length; i++){
    if(arr[i] > max){
        max = arr[i];
    }
}

2. Find the most value and its subscript in the array

Case 1: find the maximum value and its subscript for the first time

Idea:

(1) First assume the first element is Max / min

(2) Then compare max/min with the following elements one by one

Example code:

int[] arr = {4,5,6,1,9};
//Find maximum value
int max = arr[0];
int index = 0;
for(int i=1; i<arr.length; i++){
    if(arr[i] > max){
        max = arr[i];
        index = i;
    }
}

or

int[] arr = {4,5,6,1,9};
//Find maximum value
int maxIndex = 0;
for(int i=1; i<arr.length; i++){
    if(arr[i] > arr[maxIndex]){
        maxIndex = i;
    }
}
System.out.println("Maximum:" + arr[maxIndex]);

Case 2: find the subscript of the maximum value and all its maximum values (i.e. the possible maximum value is repeated)

Idea:

(1) Find the maximum value first

① Assume that the first element is the largest

② Compare max with the following elements one by one

(2) Traverse the array to see which elements are the same as the maximum value

Example code:

int[] arr = {4,5,6,1,9};
//Find maximum value
int max = arr[0];
for(int i=1; i<arr.length; i++){
    if(arr[i] > max){
        max = arr[i];
    }
}

//Traverse the array to see which elements are the same as the maximum value
for(int i=0; i<arr.length; i++){
    if(max == arr[i]){
        System.out.print(i+"\t");
    }
}

4.3.2 array statistics: sum, mean, even number, etc

Idea: traverse the array, accumulate one by one, and judge each element

Example code:

int[] arr = {4,5,6,1,9};
//Sum and mean
int sum = 0;//Because 0 plus any number does not affect the result
for(int i=0; i<arr.length; i++){
    sum += arr[i];
}
double avg = (double)sum/arr.length;

Example code 2:

int[] arr = {4,5,6,1,9};

//Total product
long result = 1;//Because multiplying 1 by any number does not affect the result
for(int i=0; i<arr.length; i++){
    result *= arr[i];
}

Example code 3:

int[] arr = {4,5,6,1,9};
//Count even numbers
int even = 0;
for(int i=0; i<arr.length; i++){
    if(arr[i]%2==0){
        even++;
    }
}

4.3.3 reverse rotation

There are two methods:

1. With a new array

2. Corresponding position exchange between head and tail

Example code of the first method:

int[] arr = {1,2,3,4,5,6,7,8,9};

//(1) Create a new array first
int[] newArr = new int[arr.length];

//(2) Copy element
int len = arr.length;
for(int i=0; i<newArr.length; i++){
    newArr[i] = arr[len -1 - i];
}

//(3) Discard the old and let arr point to the new array
arr = newArr;//Here, the first address of the new array is assigned to arr

//(4) Traversal display
for(int i=0; i<arr.length; i++){
    System.out.println(arr[i]);
}

Example code of the second method:

int[] arr = {1,2,3,4,5,6,7,8,9};

//(1) Calculate the number of times to exchange: number = arr.length/2
//(2) Head and tail exchange
for(int i=0; i<arr.length/2; i++){//The number of cycles is the number of exchanges
    //Head and tail exchange
    int temp = arr[i];
    arr[i] = arr[arr.length-1-i];
	arr[arr.length-1-i] = temp;
}

//(3) Traversal display
for(int i=0; i<arr.length; i++){
    System.out.println(arr[i]);
}

4.3.4 copying

Application scenario:

1. Capacity expansion

2. Backup

3. Intercept

Example code: capacity expansion

int[] arr = {1,2,3,4,5,6,7,8,9};

//If you want to expand the capacity of arr array, add 1 position
//(1) First create a new array, its length = the length of the old array + 1
int[] newArr = new int[arr.length + 1];

//(2) Copy element
//Note: I < arr.length because bit arr is shorter than newArr, avoid subscript out of bounds
for(int i=0; i<arr.length; i++){
    newArr[i] = arr[i];
}

//(3) Add the new element to the end of newArr
newArr[newArr.length-1] = New value;

//(4) If you continue to use arr below, you can make arr point to the new array
arr = newArr;

//(4) Traversal display
for(int i=0; i<arr.length; i++){
    System.out.println(arr[i]);
}

Example code: Backup

int[] arr = {1,2,3,4,5,6,7,8,9};

//1. Create a new array with the same length as the original array
int[] newArr = new int[arr.length];

//2. Copy element
for(int i=0; i<arr.length; i++){
    newArr[i] = arr[i];
}

//3. Traversal display
for(int i=0; i<arr.length; i++){
    System.out.println(arr[i]);
}

Example code: interception

int[] arr = {1,2,3,4,5,6,7,8,9};

int start = 2;
int end = 5;

//1. Create a new array. The length of the new array = end start + 1;
int[] newArr = new int[end-start+1];

//2. Assignment element
for(int i=0; i<newArr.length; i++){
    newArr[i] = arr[start + i];
}

//3. Traversal display
for(int i=0; i<newArr.length; i++){
    System.out.println(newArr[i]);
}

4.3.5 search

There are two types of search:

1. Sequential search: look one by one

No requirements for arrays

2. Binary search: half fold, half fold and then half fold

There are requirements for arrays, and the elements must be in size order

Sequential lookup example code:

int[] arr = {4,5,6,1,9};
int value = 1;
int index = -1;

for(int i=0; i<arr.length; i++){
    if(arr[i] == value){
        index = i;
        break;
    }
}

if(index==-1){
    System.out.println(value + "non-existent");
}else{
    System.out.println(value + "The subscript is" + index);
}

Binary search example code:

/*
2,Write code and use binary search method to find int value = 2 in the array; Whether it exists. If it exists, the subscript is displayed. If it does not exist, the display does not exist.
Known array: int[] arr = {1,2,3,4,5,6,7,8,9,10};
*/
class Exam2{
	public static void main(String[] args){
		int[] arr = {1,2,3,4,5,6,7,8,9};//Arrays are ordered
		int value = 2;
		
        int index = -1;
		int left = 0;
        int right = arr.length - 1;
        int mid = (left + right)/2;
        while(left<=right){
            //Find end
            if(value == arr[mid]){
                index = mid;
                break;
            }//Can't find
            else if(value > arr[mid]){//Continue to find to the right
                //Move the left boundary so that the mid moves to the right
                left = mid + 1;
            }else if(value < arr[mid]){//Keep looking to the left
                right = mid - 1;
            }
            
            mid = (left + right)/2;
        }
        
        if(index==-1){
    		System.out.println(value + "non-existent");
		}else{
    		System.out.println(value + "The subscript is" + index);
		}
        
	}
}

Use for

class Exam2{
	public static void main(String[] args){
		int[] arr = {1,2,3,4,5,6,7,8,9};//Arrays are ordered
		int value = 2;
		
        int index = -1;
        
        for(int left=0,right=arr.length-1,mid = (left+right)/2; left<=right; mid = (left + right)/2){
             //Find end
            if(value == arr[mid]){
                index = mid;
                break;
            }//Can't find
            else if(value > arr[mid]){//Continue to find to the right
                //Move the left boundary so that the mid moves to the right
                left = mid + 1;
            }else if(value < arr[mid]){//Keep looking to the left
                right = mid - 1;
            }
        }
        
		
        
        if(index==-1){
    		System.out.println(value + "non-existent");
		}else{
    		System.out.println(value + "The subscript is" + index);
		}
        
	}
}

4.3.6 sorting

There are thousands of sorting algorithms for arrays. We only talk about two:

1. Bubble sorting

2. Simple direct sort

Example code: bubbling: compare from small to large, from left to right

int[] arr = {5,4,6,3,1};
for(int i=1; i<arr.length; i++){//Number of outer cycles = number of rounds = length of array - 1
    /*
    Round 1, i=1, from left to right, arr[0] and arr[1]..... arr[3] and arr[4]
    Round 2, i=2, from left to right, arr[0] and arr[1]..... arr[2] and arr[3]
    ...
    				arr[j]Comparison with arr[j+1]
    Find two key points: (1) the starting value of j: 0 (2) find the ending value of j, which is 3,2,1,0, and get j < arr.length-i
    */
    for(int j=0; j<arr.length-i; j++){
        //Pairwise comparison
        //From small to large, it means that the front one is larger than the back one, so exchange it
        if(arr[j] > arr[j+1]){
            int temp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = temp;
        }
    }
}

Example code: from large to small, from right to left

char[] arr = {'h','e','l','l','o','j','a','v','a'};
for(int i=1; i<arr.length; i++){//Number of outer cycles = number of rounds = length of array - 1
    /*
    Round 1, i=1, from right to left, arr[8] and arr[7], arr[7] and arr [6] Arr [1] and arr[0]
    Round 2, i=2, from right to left, arr[8] and arr[7], arr[7] and arr [6] Arr [2] and arr[1]
    ...
    Round 8, i=8, compare from right to left, arr[8] and arr[7]
    		   arr[j]And arr[j-1]
    Find two key points: (1) the starting value of j: 8 (2) find the ending value of j, which is 1, 2, 3,... 8, j > = I
    */
    for(int j=8; j>=i; j--){
        //From large to small, the following elements > the previous elements are exchanged
        if(arr[j]>arr[j-1]){
            int temp = arr[j];
            arr[j] = arr[j-1];
            arr[j-1] = temp;
        }
    }
}	
		

Example code: simple direct selection sorting

int[] arr = {3,2,6,1,8};

for(int i=1; i<arr.length; i++){//Number of outer cycles = number of rounds = length of array - 1
    //(1) Find the latest value in the unordered elements in this round
    /*
    Unsorted elements:
    Round 1: i=1, unsorted, [0,4]
    Round 2: i=2, unsorted, [1,4]
    ...
    
    The starting subscript of each round of unordered elements: 0,1,2,3, which is exactly the starting subscript of i-1
    The following elements that are not sorted:
    Round 1: [1,4] J = 1,2,3,4
    Round 2: [2,4] J = 2,3,4
    Round 3: [3,4] J = 3,4
    Round 4: [4,4] J = 4
    j The starting point is i and the ending point is 4
    */
    int max = arr[i-1];
    int index = i-1;
    for(int j=i; j<arr.length; j++){
        if(arr[j] > max){
            max = arr[j];
            index = j;
        }
    }
    
    //(2) If the maximum value is not in the position it should be, it is exchanged with the element in this position
    /*
    In the first round, the maximum value should be [0]
    In the second round, the maximum value should be [1]
    In the third round, the maximum value should be [2]
    In the fourth round, the maximum value should be [3]
    Exactly the value of i-1
    */
    if(index != i-1){
        //Exchange arr[i-1] and arr[index]
        int temp = arr[i-1];
        arr[i-1] = arr[index];
        arr[index] = temp;
    }
}



//Display results
for(int i=0; i<arr.length; i++){
	System.out.print(arr[i]);
}

4.4 two dimensional array

Tag for 2D array: [] []

4.4.1 relevant representations

(1) Length / rows of 2D array:

Two dimensional array name length

(2) One row of 2D array:

Two dimensional array name [row subscript]

Range of row subscript: [0, 2D array name. length-1]

(3) Number of columns per row:

Two dimensional array name [row subscript] length

Because each row of a two-dimensional array is a one-dimensional array

(4) Every element

Two dimensional array name [row subscript] [column subscript]

4.4.2 declaration and initialization of two-dimensional array

1. Declaration of two-dimensional array

  //recommend
  Data type of element[][] The name of the two-dimensional array;

 //Not recommended
 The data type of the element is a two-dimensional array name[][];
 //Not recommended
  Data type of element[]  2D array name[];

interview:

int[] x, y[];
//x is a one-dimensional array and y is a two-dimensional array

2. Initialization of two-dimensional array

(1) Static initialization

2D array name = new Data type of element[][]{
			{List of values in the first row}, 
			{List of values in the second row},
			...
			{The first n List of values for row}
		};
		
//If the declaration is completed with static initialization
 Data type of element[][] The name of the two-dimensional array = {
			{List of values in the first row}, 
			{List of values in the second row},
			...
			{The first n List of values for row}
		};

(2) Dynamic initialization (irregular: the number of columns in each row may be different)

//(1) First determine the total number of rows
 2D array name = new Data type of element[Total number of rows][];

//(2) Then determine the number of columns in each row
 2D array name[Row subscript] = new Data type of element[Total number of columns in this row];

//(3) Then assign a value to the element
 2D array name[Row subscript][Column subscript] = value;

(3) Dynamic initialization (rule: the number of columns in each row is the same)

//(1) Determine the number of rows and columns
 2D array name = new Data type of element[Total number of rows][Number of columns per row];

//(2) Then assign a value to the element
 2D array name[Row subscript][Column subscript] = value;

4.4.3 traversal of two-dimensional array

for(int i=0; i<2D array name.length; i++){
    for(int j=0; j<2D array name[i].length; j++){
        System.out.print(2D array name[i][j]);
    }
    System.out.println();
}

Chapter V object oriented Foundation

5.1 class and object

1. Class: an abstract description of a class of things with the same characteristics.

Object: an individual, instance and concrete existence of a class.

Class is the design template of an object.

2. How to declare a class?

[Modifier] class Class name{
    Member list: attribute, method, constructor, code block, internal class
}

3. How to create objects?

new Class name();  //Anonymous object

Class name object name = new Class name(); //Named object

5.2 one of the members of class: attribute

1. How to declare properties?

[Modifier] class Class name{
    [Modifier] data type attribute name;    //Property has a default value
    [Modifier] data type attribute name = value; //Property has an initial value
}

Note: the type of attribute can be any type of Java, including basic data type and reference data type (class, interface, array, etc.)

Summary: Java data types

(1) Basic data type

byte,short,int,long,float,double,char,boolean

(2) Reference data type

① Class:

For example: String, Student, Circle, System, Scanner, Math

② Interface: later

③ Array:

For example: int [], String [], char [], int [] []

int[] arr = new int[5];
Here put int[]As an array type, it is a reference data type. The object assigned on the right is an array object

Data type of element: int
 Data type of array: int[]

2. How to assign values to attributes?

(1) Explicit assignment when declaring attributes

[Modifier] class Class name{
    [Modifier] data type attribute name = value; //Property has an initial value
}

Code example:

class Student{
    String name;
    char gender = 'male';//Explicit assignment
}

class TestStudent{
    public static void main(String[] args){
        Student s1 = new Student();
        System.out.println("full name:" + s1.name);//null
        System.out.println("Gender:" + s1.gender);//male
        
        s1.name = "Wei";//Modify the default value of the attribute
        s1.gender = 'female';//Modify the initial value of the attribute
        System.out.println("full name:" + s1.name);//Wei
        System.out.println("Gender:" + s1.gender);//female
        
        Student s2 = new Student();
        System.out.println("full name:" + s2.name);//null
        System.out.println("Gender:" + s2.gender);//male
    }
}

(2) Assignment after object creation

[Modifier] class Class name{
    [Modifier] data type attribute name; //Property has a default value
}

//create object
 Class name object name = new  Class name();

//Assign values to the properties of the object
 Object name.Attribute name = value;

3. How do I access the value of a property?

(1) Access in methods of this class

Example code:

class Circle{
    double radius;
    
    double getArea(){
        return 3.14 * radius * radius;//Direct access
    }
}

(2) Access in methods of other classes

class Circle{
    double radius;
}

class TestCircle{
    public static void main(String[] args){
        Circle c1 = new Circle();
        double area = 3.14 * c1.radius * c1.radius;//Object name Attribute name
    }
}

4. Characteristics of attributes

(1) Property has a default value

Basic data type:

​ byte,short,int,long: 0

​ float,double: 0.0

​ char: \u0000

​ boolean: false

Reference data type:

​ null

(2) The attributes of each object are independent and do not interfere with each other

5. Memory map of object properties

class Student{
    String name;
    char gender = 'male';//Explicit assignment
}

class TestStudent{
    public static void main(String[] args){
        Student s1 = new Student();
        System.out.println("full name:" + s1.name);//null
        System.out.println("Gender:" + s1.gender);//male
        
        s1.name = "Wei";
        s1.gender = 'female';
        System.out.println("full name:" + s1.name);//Wei
        System.out.println("Gender:" + s1.gender);//female
        
        Student s2 = new Student();
        System.out.println("full name:" + s2.name);//null
        System.out.println("Gender:" + s2.gender);//male
    }
}

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-SsTQ2s6i-1623826110068)(imgs/1558659534754.png)]

5.4 category 2: Methods

5.4.1 concept of method

method: represents an independent reusable function

Purpose / benefit:

(1) Reuse

(2) Simplify code

5.4.2 syntax of method

1. Method declaration format:

[Modifier] class Class name{
    [Modifier] return value type method name([Formal parameter list]){
        Method body: the code that implements the function
    }
}

explain:

(1) [modifier]: to be discussed

(2) Return value type:

① void: indicates no return value

② Non void: all Java data types are OK

(3) Method name: it can well reflect the function of the method

Naming norms: ① see the meaning of the name ② capitalize the first letter from the second word

(4) [formal parameter list]:

When completing the function of this method, we need some data, which should be determined by the "caller", so we can design formal parameters.

Syntax format:

(): no parameter, empty parameter

(data type parameter name): a parameter

(data type 1, parameter name 1,..., data type N, parameter name n): n parameters

(5) Method body: to realize the function of a method, the best method is to complete an independent function.

2. Method call format:

//Method call of the same level in this class: direct call
[variable = ] Method name([Argument list]);
//Call in other class methods
[variable = ] Object name.Method name([Argument list]);

(1) Pass arguments

See if the called method has formal parameters

(2) Receive return value

Check whether the called method is void. If it is void, it is unnecessary and cannot be received. If it is not void, it can be received.

3. Code example of declaration and call of method

(1) Parameterless return value method

//This category
class Circle{
    double radius;
    void printInfo(){
        System.out.println("Radius:" + radius);
    }
    
    void test(){
        printInfo();//In this class, we call no parameter no return value method.
    }
}
//Other classes
class Circle{
    double radius;
    void printInfo(){
        System.out.println("Radius:" + radius);
    }

}
class TestCircle{
    public static void main(String[] args){
        Circle c1 = new Circle();
        c1.printInfo(); //In other classes, no parameter can be returned.
    }
}

(2) Nonparametric return value method

//This category
class Circle{
    double radius;
    
    double getArea(){
        return 3.14 * radius * radius();
    }
    
    void printInfo(){
      //  System.out.println("radius:" + radius + ", area:" + getArea())// In this class, no parameter is returned and there is a return value.
       	double area = getArea();//In this class, no parameter is returned and there is a return value.
        System.out.println("Radius:" + radius + ",the measure of area:" + area);
    }
}
//Other classes
class Circle{
    double radius;
    
    double getArea(){
        return 3.14 * radius * radius();
    }
}
class TestCircle{
    public static void main(String[] args){
        Circle c1 = new Circle();
        double area = c1.getArea();
        System.out.println("the measure of area:" + area);
        //or
        System.out.println("the measure of area:" + c1.getArea());
    }
}

(3) Method with parameter and no return value

//This category
class GraphicTools{
    void printRectange(int line, int column, char sign){
        for(int i=1; i<=line; i++){
            for(int j=1; j<=column; j++){
                Sytem.out.print(sign);
            }
            System.out.println();
        }
    }
    
    void test(){
        printRectange(5,10,'%');//There is no return value method in this class.
    }
}
//Other classes
class GraphicTools{
    void printRectange(int line, int column, char sign){
        for(int i=1; i<=line; i++){
            for(int j=1; j<=column; j++){
                Sytem.out.print(sign);
            }
            System.out.println();
        }
    }
}
class Test{
    public static void main(String[] args){
        GraphicTools tools = new GraphicTools();
        tools.printRectange(5,10,'%');
    }
}

(4) Method with parameter and return value

//This category
class MyMath{
    int sum(int a,int b){
        return a+b;
    }
    
    void print(){
        int x = 4;
        int y = 7;
        System.out.println(x + "+" + y + "=" + sum(x,y);//In this class, there is a way to return values.
    }
}
//Other classes
class MyMath{
    int sum(int a,int b){
        return a+b;
    }
}
class Test{
    public static void main(String[] args){
        MyMath my = new MyMath();
        int x = 4;
        int y = 7;
        
        System.out.println(x + "+" + y + "=" + my.sum(x,y));
    }
}

4. Principles of method declaration and invocation

(1) the method must be declared before calling.

If you call a method, if the method name is written incorrectly or call a method that does not exist, the compilation will report an error

(2) The location of the method declaration must be outside the method in the class

Correct example:

class{
    Method 1(){
        
    }
    Method 2(){
        
    }
}

Examples of errors:

class{
    Method 1(){
        Method 2(){  //error
        
   		}
    }
}

(3) The calling position of the method is required

Correct example:

class{
    Method 1(){
        Call method
    }
}

Examples of errors:

class{
    Method 1(){
        
    }
    
    Call method  //error location
}

(4) The calling format of the method should correspond to the declaration format of the method

① Whether to add "object.": See whether it is in this class or in other classes

② Whether to receive the return value: check whether the called method is void

③ Whether to pass arguments: see if the called method has a formal parameter list

5.4.3 Overload of method

Concept: in the same class, there are two or more methods with the same method name and different formal parameter list. This form is called method overloading. It has nothing to do with the return value type.

Example code:

	//Find the maximum of two integers
public int max(int a,int b){
    return a>b?a:b;
}
	
	//Find the maximum of three integers
public int max(int a, int b, int c){
    return max(max(a,b),c);
}
	
	//Find the maximum of two decimals
public double max(double a, double b){
    return a>b?a:b;
}

5.4.4 parameter transfer mechanism of method

Parameter passing mechanism of method in Java: Value Passing

(1) When the formal parameter is a basic data type, the argument passes the data value to the formal parameter in the form of copy. The modification of the value by the formal parameter does not affect the actual parameter.
(2) When a formal parameter refers to a data type, the argument passes the address value to the formal parameter. The modification of the attribute of the object by the formal parameter will affect the attribute value of the actual parameter object, because at this time, the formal parameter and the actual parameter point to the same object.
Example code:

class Test{
    public static void swap(int a, int b){
        int temp = a;
        a = b;
        b = temp;
	}

	public static void main(String[] args){
        int x = 1;
        int y = 2;
        swap(x,y);//After the call, the values of x and y remain unchanged
    }
}

Example code:

class Test{
    public static void change(MyData my){
        my.num *= 2;
    }
    
    public static void main(String[] args){
        MyData m = new MyData();
        m.num = 1;
        
        change(m);//After the call, the num attribute value of the m object changes to 2
    }
}

class MyData{
    int num;
}

Trap 1:

/*
Trap 1: in the method, if the formal parameter = new object, it has nothing to do with the actual parameter
*/
class Test{
    public static void change(MyData my){
        my = new MyData();//The formal parameter points to the new object
        my.num *= 2;
    }
    
    public static void main(String[] args){
        MyData m = new MyData();
        m.num = 1;
        
        change(m);//After the call, the num attribute value of the m object is still 1
    }
}

class MyData{
    int num;
}

Trap 2: see the string and wrapper classes section

5.3 object array

One dimensional array:

1. Element is a basic data type

2. Element is a reference data type, also known as an object array, that is, the element of the array is an object

Note: for object array, first create the array object itself, that is, determine the length of the array, and then create each element object. If not, the default value of the element of the array is null, so it is easy to have null pointer exception NullPointerException.

Example code:

class MyDate{
	int year;
	int month;
	int day;
}
class Test{
    public static void main(String[] args){
        MyDate[] arr = new MyDate[3];//Create the array object itself and specify the length of the array
        
        for(int i=0; i<arr.length; i++){
            arr[i] = new MyDate();//Each element creates an object
            arr[i].year = 1990 + i;
            arr[i].month = 1 + i;
            arr[i].day = 1 + i;
        }
    }
}

Memory map of object array:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-7krCOsKi-1623826110069)(imgs/1558745138315.png)]

Chapter VI basic characteristics of object-oriented

Basic characteristics of object-oriented:

1. Encapsulation

2. Inherit

3. Polymorphism

6.1 packaging

1. Benefits:

(1) Hide the implementation details to facilitate the use of users

(2) Safe, can control the visible range

2. How to implement encapsulation?

Pass permission modifier

Interview question: Please list the permission modifiers from small to large (from large to small) according to the visible range?

Modifier This categoryThis packageSubclasses of other packagesAny position
private×××
default××
protected×
public

What can permission modifiers modify?

Classes (classes, interfaces, etc.), properties, methods, constructors, internal classes

Class (external class): public and default

Attributes: 4

Methods: 4 kinds

Constructors: 4 kinds

Internal class: 4

3. What is the usual encapsulation of attributes?

Of course, the permission modifiers of attributes can be private, default, protected and public. But most of the time, what we see is private, and then match them with get/set methods.

Example code: how to write standard Java beans

public class Student{
    //Property privatization
    private String name;
    private int age;
    private boolean marry;
    
    //Public get/set
    public void setName(String n){
        name = n;//Because we haven't learned this, we may optimize it
    }
    public String getName(){
        return name;
    }
    public void setAge(int a){
        age = a;
    }
    public int getAge(){
        return age;
    }
    public void setMarry(boolean m){
        marry = m;
    }
    public boolean isMarry(){//The get method of boolean type attribute is used to replacing get with is
        return marry;
    }
}

6.2 constructor

1. Function of constructor:
(1) Use with new to create objects

//Call parameterless construction to create an object
 Class name object name = new Class name();

//Call a parameterized construct to create an object
 Class name object name = new Class name(Argument list);

(2) You can assign values to attributes while creating objects

public class Circle{
    private double radius;
    
    public Circle(){
        
    }
    public Circle(double r){
        radius = r;//Assign a value to radius
    }
}

2. Syntax format of declaration constructor:

[Modifier] class Class name{
    [Modifier] class name(){//Nonparametric structure
        
    }
    [Modifier] class name(parameter list ){//Parametric structure
        
    }
}

3. Characteristics of constructor:

(1) All classes have constructors

(2) If a class does not explicitly / explicitly declare a constructor, the compiler will automatically add a default parameterless construct

(3) If a class explicitly / explicitly declares a constructor, the compiler will no longer automatically add the default parameterless construct. If necessary, it needs to be added manually

(4) The constructor name must be the same as the class name

(5) Constructor has no return value type

(6) Constructors can be overloaded

Example code:

public class Circle{
    private double radius;
    
    public Circle(){
        
    }
    public Circle(double r){
        radius = r;//Assign a value to radius
    }
}

6.3 keyword this

1. this keyword:

Meaning: current object

(1) If it appears in the constructor: indicates the object being created

(2) If it appears in a member method: indicates the object that is calling this method

2. Usage of this:

(1)this. attribute

When the local variable has the same name as the member variable, you can add "this." before the member variable Used to distinguish

(2)this. method

Call the member method of the current object, and you can omit "this."

(3) this() or this (argument list)

this() means to call the parameterless construction of this class

This (argument list) indicates that the parameterized construction of this class is called

this() or this (argument list) either does not exist or must appear on the first line of the constructor

Example code:

public class Student{
    private String name;
    private int score;
    
    public Student(){
        
    }
    public Student(String name){
        this.name = name;
    }
    public Student(String name, int score){
        this(name);
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setScore(int score){
        this.score = score;
    }
    public int getScore(){
        return score;
    }
}

3. What is the difference between member variables and local variables?

Only instance variables are discussed here (see the static section for class variables)

(1) The position of the declaration is different

Member variable: outside method in class

Local variables: in methods or code

① formal parameter list of method

② local variables in method body

③ local variables in code block

(2) The runtime is stored in different locations in memory

Member variables: heap

Local variables: stack

Variables of basic data type are in the stack, and variables of reference data type are in the heap: inaccurate

(3) Modifier

Member variable: there are many modifiers, such as permission modifier

Local variable: permission modifier cannot be added. The only one that can be added is final

(4) Initialize

Member variables: have default values

Local variable: it has no default value and must be initialized manually

(5) Life cycle

Member variable: it is created with the creation of the object and dies with the recycling of the object, that is, it lives and dies with the object. Each object is independent.

Local variable: it is allocated only when the method is called, and it is not available when the method runs. Each method call is independent

6.4 package

1. Function of package:

(1) Avoid duplicate class names

With a package, the full name of the class changes to: package Class name

(2) The classification organization manages many classes

For example: Java Lang package, Java Util package, Java IO package

(3) You can control the visibility of certain types or members

If the permission of a type or member is modified by default, it is only used in this package

2. Syntax format of declaration package:

package Package name;

be careful:

(1) Must be on the first line of the source file

(2) There can only be one source file

3. Naming conventions and habits of packages:
(1) All words are lowercase and used between each word division
(2) Used to invert the company's domain name

For example: com atguigu. xxx;

It is recommended that you do not use the "java.xx" package when taking the package name

4. Classes using other packages:

Premise: the permission modifier of the used class or member is > default

(1) Use the full name of the type

For example: Java util. Scanner input = new java. util. Scanner(System.in);

(2) After using the import statement, the simple name is used in the code

5. import statement

import package.Class name;
import package.*;

Note: when using the same name class of two different packages, for example: Java util. Date and Java sql. Date.

One uses the full name and one uses the simple name

Example code:

package com.atguigu.test;

import java.util.Scanner;

public class Test{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
    }
}

6.5 use of eclipse

1. eclipse manages the structure of projects and code

Workspace -- > Project -- > package – > class

A workspace can have multiple projects.

2. Shortcut key

General shortcut keys:

Ctrl + S: save

Ctrl + C: copy

Ctrl + V: paste

Ctrl + X: cut

Ctrl + Y: cancel undo

Ctrl + Z: undo

Ctrl + A: select all

Default shortcut keys in eclipse:

Ctrl + 1: quick fix

Alt + /: Code prompt

Alt + ?: Prompt for parameter list of Alt + Shift + / method

Ctrl + D: delete the selected row

Ctrl + Alt + ↓: copy line down

Ctrl + Alt + ↑: copy line up

Alt + ↓: swap position with the following line

Alt + ↑: swap position with the following line

Ctrl + Shift + F: quick format

Ctrl + /: single line comment, press again to cancel

Ctrl + Shift + /: multiline comment

Ctrl + Shift + \: uncomment multiple lines

Shift + Enter: insert SIA in the next line under the cursor to start editing

Ctrl + Shift + Enter: insert SIA on the cursor line to start editing

Alt + Shift + A: multiline editing press again to exit multiline editing mode

Alt + Shift + S: pop up the menu selection of automatic code generation, including automatic code generation constructor, get/set, equals

Ctrl + Shift + O: quick package Guide

Ctrl + Shift + T: open the source file of a class

Ctrl + O: open a summary outline of a certain type

3. Rapidly developed code templates

Code template + Alt +/

(1)main

public static void main(String[] args){

}

(2)sysout

System.out.println();

(3)for

For (int i = 0; I < array name. lenght; i + +){

}

See JavaSE Chai Linyan related tools. docx for other details

6.6 the second basic feature of object-oriented: Inheritance

1. Why inherit? The benefits of inheritance? (understanding)

(1) Code reuse

(2) Code extension

2. How to implement inheritance?

Syntax format:

[Modifier] class Subclass  extends Parent class{
    
}

3. Characteristics of inheritance

(1) The subclass inherits all the characteristics (properties, methods) of the parent class

However, private cannot be used directly in subclasses

(2) Subclasses do not inherit the constructor of the parent class

Because the constructor of the parent class is used to create the object of the parent class

(3) The constructor of the subclass must call the constructor of the parent class

While creating a subclass object, it initializes the attribute inherited from the parent class. You can assign a value to the attribute with the help of the code in the constructor of the parent class.

(4) Java only supports single inheritance: a subclass can only have one "direct" parent

(5) Java also supports multi-layer inheritance: the parent class can also have a parent class, and the features will be passed on from generation to generation

(6) A parent class can have many subclasses at the same time

6.7 keyword super

super keyword: reference the parent class, find the xx of the parent class

Usage:

(1)super. attribute

When a subclass declares a member variable with the same name as the parent class, if you want to indicate that a member variable is of the parent class, you can add "super."

(2)super. method

When a child rewrites the parent class method, it calls for the method that the parent class is rewritten in the subclass, and the "super." can be used.

(3) super() or super (argument list)

super(): it means to call the parameterless construction of the parent class

Super (argument list): refers to the parameterized construction of the calling parent class

be careful:

(1) If you want to write super() or super (argument list), you must write it in the first line of the subclass constructor

(2) If: super() or super (argument list) is not written in the constructor of the subclass, there will be super() by default

(3) If the parent class does not have a parameterless construct, write Super (argument list) in the first line of the constructor of the child class

6.8 rewriting of methods

1. Override of method

When the subclass inherits the method of the parent class and feels that the implementation of the method body of the parent class is not suitable for the subclass, the subclass can choose to override it.

2. Method rewriting requirements

(1) Method name: must be the same

(2) Formal parameter list: must be the same

(3) Modifier

Permission modifier: >=

(4) Return value type

In case of basic data type and void: must be the same

If it is a reference data type:<=

In Java, we believe that in the conceptual scope: subclass < parent class

3. The difference between Overload and Override

Overload: two or more methods in the same class with the same method name, different formal parameter list and independent of the return value type.

Override: between parent and child classes. The requirements for method signature are shown above.

Special heavy load:

public class TestOverload {
	public static void main(String[] args) {
		B b = new B();
		//b object can call several a methods
		b.a();
		b.a("");//From the point of view that b object has two methods with the same name and different formal parameters at the same time, it is overloaded
	}
}
class A{
	public void a(){
		//...
	}
}
class B extends A{
	public void a(String str){
		
	}
}

6.9 non static code block

1. Syntax format

[Modifier] class Class name{
    {
        Non static code block
    }
}

2. Function

Purpose: in the process of creation, assign values to object attributes to assist in the process of instance initialization

3. When will it be implemented?

(1) Executes each time an object is created

(2) Takes precedence over constructor execution

6.10 instance initialization process

1. Concept description

  • Instance initialization process: the process of creating an instance object

  • Instance initialization method: the method to be executed when creating an instance object

  • The origin of instance initialization method: it is compiled and generated by compiler

  • Form of instance initialization method: () or (formal parameter list)

  • Composition of instance initialization method:

    ① Explicit assignment code for attribute

    ② Code for non static code blocks

    ③ Constructor code

    among

    ① And ② in order, from top to bottom

    ③ Behind ① and ②

Therefore, if a class has several constructors, there are several instance initialization methods.

2. Single class instance initialization method

Example code:

class Demo{
	{
		System.out.println("Non static code block 1");
	}
	
	private String str = assign();//Call the method to explicitly assign a value to str
	
	public Demo(){
		System.out.println("Nonparametric structure");
	}
	public Demo(String str){
		this.str = str;
		System.out.println("Parametric structure");
	}
	
	{
		System.out.println("Non static code block 2");
	}
	
	public String assign(){
		System.out.println("assign method");
		return "hello";
	}
}

Illustration:

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-nG9qJjHU-1623826110070)(imgs/1558960549421.png)]

3. Instance initialization of parent and child classes

be careful:

(1) Originally, super() and super (argument list) were said to be constructors that call the parent class. Now it is necessary to correct it to call the instance initialization method of the parent class

(2) Originally, super() and super (argument list) said that they must be in the first line of the subclass constructor. Now, it should be corrected to be in the first line of the subclass instance initialization method

Conclusion:

(1) The execution order is to initialize the parent class instance first and then the child class instance

(2) If a subclass overrides a method and is called through a subclass object, the overridden method must be executed

Example code:

class Ba{
	private String str = assign();
	{
		System.out.println("(1)Non static code block of parent class");
	}
	public Ba(){
		System.out.println("(2)Parameterless construction of parent class");
	}
	public String assign(){
		System.out.println("(3)Parent class assign()");
		return "ba";
	}
}
class Er extends Ba{
	private String str = assign();
	{
		System.out.println("(4)Non static code block of subclass");
	}
	public Er(){
		//Super () = = > calls the instance initialization method of the parent class, and it is in the first line of the instance initialization method of the child class
		System.out.println("(5)Nonparametric construction of subclasses");
	}
	
	public String assign(){
		System.out.println("(6)Subclass assign()");
		return "er";
	}
}
class Test{
    public static void main(String[] args){
        new Er();//612645
    }
}

Illustration:

[the external chain picture transfer fails. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-qwp4cx8-1623826110071) (IMGs / 1558961723911. PNG)]

6.11 the third basic feature of object-oriented: polymorphism

1. Polymorphism:

Syntax format:

Parent class reference/variable = Subclass object;

2. Premise:

(1) Inherit

(2) Method rewriting

(3) Polymorphic reference

3. Phenomenon:

When compiling, look at the left / "parent class", and when running, look at the right / "child class".

During compilation, because the compilation is based on the parent class, only the methods of the parent class can be used, and the methods extended by the child class cannot be called;

The execution time must be the method body overridden by the running subclass.

Example code:

class Person{
	public void eat(){
		System.out.println("having dinner");
	}
	public void walk(){
		System.out.println("walk");
	}
}
class Woman extends Person{
	public void eat(){
		System.out.println("Eat slowly");
	}
	public void walk(){
		System.out.println("Graceful walking");
	}
	public void shop(){
		System.out.println("buy whatever you want...");
	}
}
class Man extends Person{
	public void eat(){
		System.out.println("A voracious meal");
	}
	public void walk(){
		System.out.println("Swagger");
	}
	public void smoke(){
		System.out.println("smoke opium");
	}
}
class Test{
    public static void main(String[] args){
        Person p = new Woman();//Polymorphic reference
        p.eat();//Perform subclass overrides
        p.walk();//Perform subclass overrides
        //p.shop();// Cannot call
    }
}

4. Application:

(1) Polymorphic parameter: the formal parameter is the parent class and the actual parameter is the subclass object

(2) Polymorphic array: the array element type is the parent class, and the element stores the subclass objects

Example code: polymorphic parameters

class Test{
    public static void main(String[] args){
        test(new Woman());//Arguments are subclass objects
        test(new Man());//Arguments are subclass objects
    }
    public static void test(Person p){//Formal parameter is a parent type
        p.eat();
        p.walk();
    }
}

Example code: polymorphic array

class Test{
    public static void main(String[] args){
        Person[] arr = new Person[2];//Polymorphic array
        arr[0] = new Woman();
        arr[1] = new Man();
        
        for(int i=0; i<arr.length; i++){
            all[i].eat();
            all[i].walk();
        }
    }
}

5. Transformation up and down: transformation between parent and child classes

(1) Upward Transformation: automatic type conversion

When the object of the subclass is assigned to the variable of the parent class (i.e. polymorphic reference), the object will be transformed upward into the parent class at compile time. At this time, you can't see the "unique and extended" methods of the subclass.

(2) Downward Transformation: forced conversion. If there is a risk, ClassCastException may be reported.

When you need to assign a parent class variable to a child class variable, you need to transition down.

To succeed in the transformation, you must ensure that the runtime type of the object saved in the variable is < = forced transformation type

Example code:

class Person{
	//Method code omitted
}
class Woman extends Person{
    //Method code omitted
}
class ChineseWoman extends Woman{
	//Method code omitted
}
 public class Test{
     public static void main(String[] args){
		//Upward transformation
		Person p1 = new Woman();
		//Downward transformation
		Woman m = (Woman)p1; 
		//The object actually stored in the p1 variable is the Woman type, which is the same as the strongly converted Woman type

		//Upward transformation
		Person p2 = new ChineseWoman();
		//Downward transformation
		Woman w2 = (Woman) p2; 
		//The actual stored object in the p2 variable is of Chinese Woman type, the mandatory type is of Chinese type, and Chinese Woman < of Chinese type     
     }
 }

6,instanceof

Expression syntax format:

object/variable  instanceof  type

Operation result: true or false

effect:

It is used to determine whether the object belongs to this type, or whether it is an object of this type or an object of a subclass of this type

Example code:

class Person{
	//Method code omitted
}
class Woman extends Person{
    //Method code omitted
}
class ChineseWoman extends Woman{
	//Method code omitted
}
 public class Test{
     public static void main(String[] args){
         Person p = new Person();
         Woman w = new Woman();
         ChineseWoman c = new ChineseWoman();
         
         if(p instanceof Woman){//false
             
         }
         if(w instanceof Woman){//true
             
         }
         if(c instanceof Woman){//true
             
         }
     }
 }

Chapter 7 advanced features of object-oriented

The study of modifiers revolves around three questions:

(1) The meaning of the word

(2) What can be modified?

(3) What's the difference with it?

7.1 keyword: final

final: final

Usage:

(1) Decoration class (including external class and internal class)

Indicates that this class cannot be inherited and has no subclasses

(2) Modification method

Indicates that this method cannot be overridden

(3) Modifier variable (member variable (class variable, instance variable), local variable)

Indicates that the value of this variable cannot be modified

Note: if a member variable is modified with final, it must also be assigned manually, and once this value is assigned, it cannot be modified, that is, there is no set method

7.2 keyword: native

native: native
Usage:

Can only modify methods

The method body code representing this method is not implemented in the Java language.

But for Java programmers, you can call it normally as a Java method, or subclass rewrite it.

JVM memory management:

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-hfjQfKM8-1623826110072)(imgs/1555119319865.png)]

Method area: class information, constants, static variables, bytecode information generated by dynamic compilation

Virtual machine stack: local variables of methods implemented in Java language

Local method stack: the local variable of the method implemented in non Java language, that is, the memory area when the native method is executed

Heap: new objects

Program counter: records which instruction each thread currently executes

7.3 keyword: static

Static: static

Usage:

1. Member methods: we generally call them static methods or class methods

(1) Cannot be overridden

(2) Used

In this class: it can be used directly in other methods

In other classes, "class name. Method" can be used for calling, and "object name. Method" can also be used. It is recommended to use "class name. Method"

(3) In static methods, we can't appear: this, super, non static members

2. Member variable: we generally call it static variable or class variable

(1) The value of a static variable is shared by all objects of this class

(2) Static variables are stored in the method area

(3) The get/set corresponding to a static variable is also static

(4) When static variables and local variables have the same name, you can use "class name. Static variables" to distinguish them

3. Internal class: later

4. Code blocks: static code blocks

5. Static import (JDK1.5 import)

No static import

package com.atguigu.utils;

public class Utils{
    public static final int MAX_VALUE = 1000;
    public static void test(){
        //...
    }
}


package com.atguigu.test;

import com.atguigu.utils;

public class Test{
    public static void main(String[] args){
        System.out.println(Utils.MAX_VALUE);
        Utils.test();
    }
}

Use static import

package com.atguigu.utils;

public class Utils{
    public static final int MAX_VALUE = 1000;
    public static void test(){
        //...
    }
}
package com.atguigu.test;

import static com.atguigu.utils.Utils.*;

public class Test{
    public static void main(String[] args){
        System.out.println(MAX_VALUE);
        test();
    }
}

7.4 static code block

1. Syntax format:

[Modifier] class Class name{
    static{
        Static code block;
    }
}

2. Function:

Assist in class initialization and assign values to class variables.

3. Class initialization ()

Class initialization includes:

① Explicit assignment code of static variables

② Code in static code block

① and ② are executed in sequence

Note: there is only one class initialization method

4. Execution characteristics of class initialization:

(1) The () of each class is executed only once

(2) If a subclass finds that the parent class is not initialized during initialization, the parent class will be initialized first

(3) If you want both class initialization and instantiation initialization, you must complete class initialization first

7.5 classification and difference of variables

1. Variables are divided by data type:

(1) Variables of basic data type, in which data values are stored

(2) Reference data type variables, which store the address value of the object

int a = 10;//Data values are stored in a

Student stu = new Student();//stu stores the address value of the object
int[] arr = new int[5];//arr stores the address value of the array object
String str = "hello";//str stores the address value of the "hello" object

2. Variables vary according to the declared location:

(1) Member variable

(2) Local variable

3. Differences between member variables and local variables

(1) The position of the declaration is different

Member variable: outside method in class

Local variable: (1) in () of the method, that is, in the local variable of {} of the formal parameter (2) method body (3) in the code block {}

(2) Different storage locations

Member variables:

If it is a static variable (class variable), in the method area

If it is a non static variable (instance variable), it is in the heap

Local variables: stack

(3) Different modifiers

Member variables: 4 kinds of permission modifiers, static, final....

Local variable: only final

(4) Life cycle

Member variables:

If it is a static variable (class variable), it is the same as the class

If it is a non static variable (instance variable), it is the same as the object to which it belongs, and each object is independent

Local variables: new for each execution

(5) Scope

Member variables:

If it is a static variable (class variable), use it casually in this class and use "class name. Static variable" in other classes“

If it is a non static variable (instance variable), it can only be used in non static members in this class, and "object name. Non static variable" can be used in other classes“

Local variables: scoped

7.7 root parent class

1,java.lang.Object class is the root parent class of class hierarchy. Include array objects.

(1) All methods declared in the Object class will be inherited into subclasses, that is, all objects have methods in the Object class

(2) Each Object creation will eventually call the Object instance initialization method ()

(3) Object type variables, formal parameters and arrays can store objects of any type

2. Common methods of Object class

(1)public String toString():

① By default, the return is the hexadecimal form of "object's runtime type @ object's hashCode value"“

② It is usually recommended to rewrite. In eclipse, you can use Alt +Shift + S – > generate tostring()

③ If we go straight to system out. Println (object), the toString() of this object will be called automatically by default

(2)public final Class<?> Getclass(): get the runtime type of the object

(3) protected void finalize(): when an object is determined by GC as garbage to be recycled, GC will call this method for you before recycling. And this method will only be called once. Subclasses can optionally override.

(4) public int hashCode(): returns the hash value of each object.

Regulations: ① if the hash values of two objects are different, the two objects must not be equal;

② if the hash values of two objects are the same, the two objects are not necessarily equal.

It is mainly used to improve performance when the object is stored in a hash table.

(5) public boolean equals(Object obj): used to judge whether the current object this is "equal" to the specified object obj

① By default, the implementation of the equals method is equivalent to "= =", comparing the address value of the object

② We can choose to rewrite some requirements:

A: If equals is rewritten, the hashCode() method must be rewritten together, because it stipulates:

a: if two objects call equals and return true, the hashCode values of the two objects must be equal;

b: if the hashCode values of two objects are different, it must be false for the two objects to call the equals method;

c: if the hashCode values of two objects are the same, the two objects may call equals either true or false

B: If you rewrite equals, you must follow the following principles:

a: Reflexivity: x.equals(x) returns true

b: transitivity: x.equals(y) is true, y.equals(z) is true, and then x.equals(z) should also be true

c: consistency: as long as the attribute values involved in equals comparison are not modified, the call results should be consistent at any time

d: symmetry: the results of x.equals(y) and y.equals(x) should be the same

e: non empty objects and null equals must be false

7.8 keyword: abstract

1. When will abstract methods and classes be used?

When declaring a parent class, the implementation of the method body of some methods in the parent class cannot be determined, but can only be determined by the child class. However, the common characteristics of subclasses should be reflected in the parent class, that is, it should include this method in order to uniformly manage the objects of each subclass, that is, for the application of polymorphism.

At this point, you can choose to declare such a method as an abstract method. If a class contains abstract methods, the class must be an abstract class.

2. Syntax format of abstract class

[Permission modifier] abstract class Class name{
    
}
[Permission modifier] abstract class Class name extends Parent class{
    
}

3. Syntax format of abstract method

[Other modifiers] abstract Return value type method name([Formal parameter list]);

Abstract method has no method body

4. Characteristics of abstract classes

(1) Abstract classes cannot be instantiated directly, that is, new objects cannot be instantiated directly

(2) Abstract classes are used to be inherited. After a subclass inherits an abstract class, it must override all abstract methods, otherwise the subclass must also be an abstract class

(3) the abstract class also has a constructor. The function of this structure is not to create the object of the abstract class, but to call the subclass in the instantiation process.

(4) Abstract classes can also have no abstract methods, so the purpose is not to let you create objects, but to let you create objects of its subclasses

(5) Variables of an abstract class and objects of its subclasses also constitute polymorphic references

5. Modifier that cannot be used with abstract?

(1) Final: and final cannot modify methods and classes together

(2) Static: and static cannot modify methods together

(3) Native: and native cannot modify methods together

(4) Private: and private cannot modify methods together

7.9 interface

1. Concept of interface

Interface is a standard. Pay attention to the standards of conduct (i.e. methods).

There is one principle of object-oriented development: interface oriented programming.

2. Declaration format of interface

[Modifier] interface Interface name{
    Member list of interface;
}

3. Class implements the format of the interface

[Modifier] class Implementation class  implements Parent interfaces{
    
}

[Modifier] class Implementation class extends Parent class implements Parent interfaces{
    
}

4. Interface inherits the format of the interface

[Modifier] interface Interface name extends Parent interfaces{
    Member list of interface;
}

5. Characteristics of interface

(1) Interfaces cannot be instantiated directly, that is, new objects cannot be instantiated directly

(2) If only connected implementation class objects can be created, polymorphic references can be formed between the interface and its implementation class objects.

(3) When implementing an interface, the implementation class must override all abstract methods, otherwise the implementation class must also be an abstract class.

(4) Java stipulates that there can only be single inheritance between classes, but there is a multi implementation relationship between Java classes and interfaces, that is, a class can implement multiple interfaces at the same time

(5) Java also supports multiple inheritance between interfaces.

6. Members of the interface

JDK1. Before 8:

(1) Global static constants: public static final. These modifiers can be omitted

(2) Public Abstract: public abstract. These modifiers can also be omitted

JDK1. After 8:

(3) Public static method: public static, which cannot be omitted

(4) Public default method: public default, which cannot be omitted

7. Default method conflict problem

(1) When an implementation class implements two or more interfaces at the same time, the signatures of the default methods of the multiple interfaces are the same.

Solution:

Scheme 1: choose to keep one of them

Interface name.super.Method name([Argument list]);

Scheme 2: complete rewriting

(2) When an implementation class inherits the parent class and implements the interface at the same time, a method in the parent class has the same signature as the default method of the interface

Solution:

Scheme 1: the default scheme keeps the parent class

Scheme 2: select to keep the interface

Interface name.super.Method name([Argument list]);

Scheme 3: complete rewriting

8. Sample code

public interface Flyable{
	long MAX_SPEED = 7900000;
    void fly();
}
public class Bird implements Flyable{
    public void fly(){
        //....
    }
}

9. Common interfaces

(1)java.lang.Comparable interface: natural sorting

Abstract method: int compareTo(Object obj)

(2)java.util.Comparator interface: custom sorting

Abstract method: int compare (object obj1, object obj2)

(3) Sample code

If the employee type, the default order and the natural order are arranged in ascending order, then the Comparable interface is implemented

class Employee implements Comparable{
    private int id;
    private String name;
    private double salary;
    
    //Constructor, get/set,toString are omitted
    
    @Override
    public int compareTo(Object obj){
        return id - ((Employee)obj).id;
    }
}

If you find new requirements later and want to sort by salary, you can only choose to use custom sorting to implement the Comparator interface

class SalaryComparator implements Comparator{
    public int compare(Object o1, Object o2){
        Employee e1 = (Employee)o1;
        Employee e2 = (Employee)o2;
        if(e1.getSalary() > e2.getSalary()){
            return 1;
        }else if(e1.getSalary() < e2.getSalary()){
            return -1;
        }
        return 0;
    }
}

7.10 internal class

1. Concept of inner class

A class declared in another class is an inner class.

2. Four forms of internal classes

(1) Static inner class

(2) Non static member inner class

(3) Local inner class with name

(4) Anonymous inner class

7.10.1 anonymous inner class

1. Syntax format:

//Calling the anonymous structure of the parent class in the anonymous sub class
new Parent class(){
    Member list of inner class
}

//Calling the parameter structure of the parent class in the anonymous sub class
new Parent class(Argument list){
    Member list of inner class
}

//If the interface does not have a constructor, it means that the unnamed subclass calls its own parameterless construction and the parameterless construction of the default parent class Object
new Parent interface name(){
    
}

2. What is the difference between anonymous inner classes and anonymous objects?

System.out.println(new Student("Zhang San"));//Anonymous object

Student stu = new Student("Zhang San");//This object has a name, stu

//It has both an anonymous inner class and an anonymous object
new Object(){
    public void test(){
        .....
    }
}.test();

//The Object of this anonymous inner class uses the name obj to refer to it. The Object has a name, but the subclass of this Object has no name
Object obj = new Object(){
    public void test(){
        .....
    }
};

3. Form used

(1) Example code: inherited

abstract class Father{
    public abstract void test();
}
class Test{
    public static void main(String[] args){
        //Use the objects of parent class and anonymous inner class to form polymorphic references
        Father f = new Father(){
            public void test(){
                System.out.println("Inherited with anonymous inner class Father This abstract class is overridden test Abstract method")
            }
        };
        f.test();
    }
}

(2) Example code: Implementation

interface Flyable{
    void fly();
}
class Test{
    public static void main(String[] args){
        //The parent interface and the object of the anonymous inner class form a polymorphic reference
        Flyable f = new Flyable(){
            public void fly(){
                System.out.println("Implemented with anonymous inner classes Flyable This interface overrides the abstract method");
            }
        };
        f.fly();
    }
}

(3) Example code: call a method directly with an anonymous object of an anonymous inner class

new Object(){
    public void test(){
        System.out.println("Call the method directly with the anonymous object of the anonymous inner class")
    }
}.test();

(4) Example code: use the anonymous object of the anonymous inner class as the argument directly

Student[] all = new Student[3];
all[0] = new Student("Zhang San",23);
all[1] = new Student("Li Si",22);
all[2] = new Student("Wang Wu",20);

//Use the anonymous object of the anonymous inner class as the argument directly
//This anonymous inner class implements the Comparator interface
//The object of this anonymous inner class is the object of the custom comparator
Arrays.sort(all, new Comparator(){
    public int compare(Obeject o1, Object o2){
        Student s1 = (Student)o1;
        Student s2 = (Student)o2;
        return s1.getAge() - s2.getAge();
    }
});

7.10.2 static internal class

1. Syntax format

[Modifier] class External class name[ extends Parent of external class][ implements Parent interface of external class]{
	[Other modifiers] static class  Static inner class[ extends Static internal class [its own parent][ implements Parent interfaces of static inner classes]{
        Member list of static inner class;
	}
	
	List of other members of the external class;
}

2. Precautions for use

(1) Whether the included members have requirements:

Can contain all members of a class

(2) Modifier requirements:

  • Permission modifiers: 4 kinds
  • Other modifiers: abstract, final

(3) Are there requirements on members using external classes

  • Only static members of external classes can be used

(4) Is there a requirement to use static inner classes in outer classes

  • Normal use

(5) Is there a requirement to use static inner classes outside the outer classes

(1)If you are using static members of a static inner class
		External class name.Static internal class name.Static member
(2)If you are using non static members of a static inner class
		①First create the object of the static inner class
		External class name.Static internal class name object name = new External class name.Static internal class name([Argument list]);
		②Calling non static members through objects
		Object name.xxx

(6) Bytecode file form: external class name $static internal class name class

3. Sample code

class Outer{
    private static int i = 10;
    static class Inner{
        public void method(){
            //...
            System.out.println(i);//sure
        }
        public static void test(){
            //...
            System.out.println(i);//sure
        }
    }
    
    public void outMethod(){
        Inner in = new Inner();
        in.method();
    }
    public static void outTest(){
        Inner in = new Inner();
        in.method();
    }
}
class Test{
    public static void main(String[] args){
        Outer.Inner.test();
        
        Outer.Inner in = new Outer.Inner();
        in.method();
    }
}

7.10.3 non static internal class

1. Syntax format

[Modifier] class External class name[ extends Parent of external class][ implements Parent interface of external class]{
	[Modifier] class  Non static inner class[ extends Non static internal class [its own parent][ implements Parent interface of non static inner class]{
        Member list of non static inner class;
	}
	
	List of other members of the external class;
}

2. Precautions for use

(1) Whether the included members have requirements:

Static members are not allowed

(2) Modifier requirements

Permission modifiers: 4 kinds

Other modifiers: abstract, final

(3) Are there requirements on members using external classes

Can be used

(4) Is there a requirement to use non static inner classes in outer classes

Non static inner classes cannot be used in static members of an outer class

(5) Is there a requirement to use non static inner classes outside the outer class

//Use non static members of non static inner classes
//(1) Create an object of an external class
 External class name object name 1 = new  External class name([Argument list]);

//(2) Create or obtain the object of non static internal class through the object of external class
//establish
 External class name.Non static internal class name object name 2 = Object name 1.new Non static internal class name([Argument list]);

//obtain
 External class name.Non static internal class name object name 2 = Object name 1.get Methods of non static internal class objects([Argument list]);

//(3) Call its non static members through a non static inner class
 Object name 2.xxx

(6) Bytecode file form: external class name $non static internal class name class

3. Sample code

class Outer{
    private static int i = 10;
    private int j = 20;
    class Inner{
        public void method(){
            //...
            System.out.println(i);//sure
            System.out.println(j);//sure
        }
    }
    
    public void outMethod(){
        Inner in = new Inner();
        in.method();
    }
    public static void outTest(){
       // Inner in = new Inner();// may not
    }
    
    public Inner getInner(){
        return new Inner();
    }
}
class Test{
    public static void main(String[] args){
        Outer out = new Outer();
        
        Outer.Inner in1 = out.new Inner();     //establish   	
        in1.method();
        
        Outer.Inner in2 = out.getInner();	//obtain
        in2.method();
    }
}

7.10.4 local internal class

1. Syntax format

[Modifier] class External class name[ extends Parent of external class][ implements Parent interface of external class]{
	[Modifier] return value type method name([Formal parameter list]){
        [Modifier] class  Local inner class[ extends Local internal class [its own parent][ implements Parent interfaces of local internal classes]{
        	Member list of local inner class;
		}
	}	
	List of other members of the external class;
}

2. Precautions for use

(1) Are there any requirements for the included members

Static members are not allowed

(2) Modifier requirements

Permission modifier: cannot

Other modifiers: abstract, final

(3) Are there requirements for using members of external classes

① use static members of external classes: use them casually

② use non static members of external classes: whether they can be used depends on whether the method is static

③ local variable of the method used: it must be modified by final

(4) Is it required to use local inner classes in external classes

Have scope

(5) Is there a requirement to use local inner classes outside the outer class

Can't use

(6) Bytecode file form: external class name $number, local internal class name class

3. Sample code

class Outer{
    private static int i = 10;
    private int j = 20;

    
    public void outMethod(){
        class Inner{
            public void method(){
                //...
                System.out.println(i);//sure
                System.out.println(j);//sure
            }
   		}
        Inner in = new Inner();
        in.method();
    }
    public static void outTest(){
        final int k = 30;
       class Inner{
            public void method(){
                //...
                System.out.println(i);//sure
                System.out.println(j);//may not
                System.out.println(k);//sure
            }
   		}
        Inner in = new Inner();
        in.method();
    }
}

Chapter VIII enumeration and annotation

8.1 enumeration

1. Enumeration (introduced by JDK1.5)

Objects of enumeration type are limited and fixed constant objects.

2. Syntax format

//Form 1: there is only a list of constant objects in the enumeration type
[Modifier] enum Enumeration type name{
    Constant object list
}

//Form 2: there is only a constant object list in the enumeration type
[Modifier] enum Enumeration type name{
    Constant object list;
    
    List of other members;
}

Description: the list of constant objects must be in the first line of enumeration type

Recall: first line

(1) super() or super (argument list): must be in the first line of subclass constructor

(2) this() or this (argument list): must be in the first line of this class constructor

(3) Package; The statement declaring the package must be in the source file First line of java code

(4) The list of enumeration constant objects must be in the first line of the enumeration type

3. How to get enumerated constant objects in other classes

//Get a constant object
 Enumeration type name.Constant object name

//Get a constant object
 Enumeration type name.valueOf("Constant object name")
    
//Get all constant objects
 Enumeration type name[] all = Enumeration type name.values();

4. Characteristics of enumeration types

(1) Enumeration types have a common basic parent class, which is Java Lang. enum type, so you can't inherit other types

(2) Constructor of enumeration type must be private

(3) Enumeration types can implement interfaces

interface MyRunnable{
    void run();
}
enum Gender implements MyRunnable{
    NAN,NV;
    public void run(){
        //...
    }
}
//or
enum Gender implements MyRunnable{
    NAN{
        public void run(){
       	 //...
    	}
    },NV{
        public void run(){
        //...
   		}
    };
    
}

5. Parent class java Lang. enum type

(1) Constructor

protected Enum(String name, int ordinal): automatically called by the compiler

(2) String name(): constant object name

(3) int ordinal(): returns the ordinal number of the constant object. The first ordinal number is 0

(4) String toString(): returns the name of the constant object. If the subclass wants to override it, it needs to be rewritten manually

(5) int compareTo(Object obj): compare in the order of constant objects

8.2 notes

1. Annotation

It is a code level comment

2. Marking symbol:@

3. Three basic annotations predefined by the system:

(1) @ Override: indicates that a method is an overridden method

It can only be used on methods. It will let the compiler check the format of this method to see if it meets the rewriting requirements

(2) @ SuppressWarnings(xx): suppress warnings

(3) @ Deprecated: indicates that xx is out of date

4. Notes related to document notes

(1) Document notes

/**
Documentation Comments 
*/

(2) Common document notes

@author: author

@since: added from version xx

@see: please also refer to

@param: formal parameter

@Return: return value

@throws or @ exception: exception

5. Several notes related to JUnit

(1) @ Test: indicates that it is a unit Test method

This method needs to be: public void xxx() {}

(2) @ Before: means to execute Before each unit test method

This method needs to be: public void xxx() {}

(3) @ After: means to execute After each unit test method

This method needs to be: public void xxx() {}

(4) @ BeforeClass: indicates that it is executed during class initialization and only once

This method needs to be: public static void xxx() {}

(3) @ AfterClass: indicates that it is executed in the "uninstall" phase of the class and only once

This method needs to be: public static void xxx() {}

6. Meta annotation

(1) @ Target(xx): the annotation marked with it can be used in xx position

(xx): specified by 10 constant objects of ElementType enumeration TYPE, for example: TYPE, METHOD, FIELD, etc

For example:

@Target(ElementType.TYPE)

@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
import static java.lang.annotation.ElementType.*;


@Target({TYPE,METHOD,FIELD})

(2) @ Retention (xx): the annotation marked with it can stay in the xx stage

(xx): specified by three constant objects of RetentionPolicy enumeration type: SOURCE, CLASS and RUNTIME

Only annotations in the RUNTIME phase can be read by reflection

For example:

@Retention(RetentionPolicy.RUNTIME)

(3) @ Documentd: the annotation marked with it can be read into the API

(4) @ Inherited: the annotation marked with it can be Inherited by subclasses

7. Custom annotation

@Meta annotation
[Modifier] @interface Annotation name{
    
}

@Meta annotation
[Modifier] @interface Annotation name{
    Configuration parameter list
}

Syntax format of configuration parameters:

Data type configuration parameter name();

or

Data type configuration parameter name() default Default value;

About configuration parameters:

(1) The type of configuration parameters requires:

Eight basic data types, String, enumeration, Class type, annotation, and their arrays.

(2) If a custom annotation declares a configuration parameter, the configuration parameter must be assigned a value when using this annotation, unless it has a default value

@Custom annotation name(Configuration parameter name 1=Value, configuration parameter name 2=Value...)

//If the configuration parameter type is array, the array can be represented by {} during assignment
@Custom annotation name(Configuration parameter name 1={value},Configuration parameter name 2=Value...)

(3) If there is only one configuration parameter and the name is value, value can be omitted during assignment=

(4) If you want to get the value of the configuration parameter when reading this annotation, you can access it as a method

Custom annotation object.configuration parameter();

Chapter IX exceptions

9.1 architecture of exception types

1. Supersuperclass of exception series: Java lang.Throwable

(1) Only the objects of it or its subclasses can be "thrown" out by the JVM or throw statement

(2) Only the objects of it or its subclasses can be caught

2. Throwable is divided into two factions

(1) Error: a serious error. You need to stop, redesign and upgrade to solve this problem

(2) Exception: general exception, which can be avoided through judgment and inspection, or handled with try... catch

3. Exception s fall into two categories

(1) Runtime exception:

It is an object of RuntimeException or its subclass.

For this type of exception, the compiler will not remind you to throw or try... catch, but the runtime may cause a crash.

(2) Compile time exception:

Exceptions except runtime exceptions are compile time exceptions.

For this type of exception, the compiler forces you to handle throws or try... catch, otherwise the compilation fails.

4. List common exception types

(1) Runtime exception

RuntimeException, NullPointerException (null pointer exception), ClassCastException (type conversion exception), arithmetexception (arithmetic exception), NubmerFormatException (number formatting exception), IndexOutOfBoundsException (subscript out of bounds exception) (ArrayIndexOutOfBoundsException) StringIndexOutOfBoundsException, InputMisMatchException....

(2) Compile time exception

FileNotFoundException (exception not found in the file), IOException (input / output exception), SQLException (database sql statement execution exception)...

9.2 exception handling

1. Handle in current method: try... catch... finally

//Form 1: try catch
try{
    Possible exception codes
}catch(Exception type exception name e){
    Code for handling exceptions (usually statements that print exception information)
}catch(Exception type exception name e){
    Code for handling exceptions (usually statements that print exception information)
}. . . 


//Form 2: try finally
try{
    Possible exception codes
}finally{
    whether try Whether there is any abnormality in the, whether or not there is return,The part to be executed
}

//Form 3: try catch.. finally
try{
    Possible exception codes
}catch(Exception type exception name e){
    Code for handling exceptions (usually statements that print exception information)
}catch(Exception type exception name e){
    Code for handling exceptions (usually statements that print exception information)
}. . . 
finally{
    whether try It doesn't matter whether there are exceptions in the catch It doesn't matter whether you can catch exceptions try and catch Is there any in the return,The part to be executed
}

Execution features:

(1) If there is no exception in the code in the try, the code in the try will execute normally, the catch part will not execute, and finally will execute

(2) If the code in the try has an exception, the code with an exception in the try will not be executed. Find the corresponding catch branch for execution, and finally it will be executed

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-0Z2sajxJ-1623826110074)(imgs/1559610439025.png)]

2. When finally and return are mixed

(1) If there is a return in finally, it must be returned from the return in finally.

At this time, the return statement in try and catch is half executed and the first action is executed. Therefore, the return statement in finally will overwrite the just returned value

Return return value; The statement has two actions: (1) put the return value into the "operand stack". After the current method is completed, the value in the "operand stack" will be returned to the caller; (2) end the execution of the current method

(2) If there is no return in finally, the statement in finally will be executed, but the final return value will not be affected

That is, the return statements in try and catch are separated in two steps. First, (1) put the return value into the "operand stack" (2) then go to the statement in finally (3) and then execute the second half of return to end the current method

3. Do not handle exceptions in the current method, and explicitly throw them to the caller for processing. Use throws

Syntax format:

[Modifier] return value type method name([Formal parameter list]) throws Exception list{
    
}

At this point, the caller knows what exceptions need to be handled.

Requirements for method Rewriting:

(1) Method name: same

(2) Formal parameter list: same

(3) Return value type:

Basic data type and void: the same

Reference data type:<=

(4) Modifier:

Permission modifier: >=

Other modifiers: static, final, private cannot be overridden

(5)throws: <=

Method overload:

(1) Method name: same

(2) Formal parameter list: must be different

(3) Return value type: irrelevant

(4) Modifiers: irrelevant

(5) throws: irrelevant

9.3 exception thrown manually: throw

throw Exception object;

//For example:
throw new AccountException("xxx");

Like the exception object thrown by the JVM, the exception object thrown by throw should also be handled with try... catch or throws.

If it is a runtime exception, the compiler will not force you to handle it. If it is a compile time exception, the compiler will force you to handle it.

9.4 custom exception

1. You must inherit Throwable or its subclasses

We often see the inheritance of RuntimeException and Exception

If you inherit RuntimeException or its subclass, the exception you customize is a runtime exception. The compiler won't remind you to handle it.

If you inherit Exception, it belongs to compile time Exception, and the compiler will force you to handle it.

2. I suggest you keep two constructors

//Nonparametric structure
public Custom exception name(){
    
}

//Parametric structure
public Custom exception name(String message){
    super(message);
}

3. Custom exception objects must be thrown manually and thrown with throw

9.5 several methods of exception

(1) e.printStackTrace(): print the details of the exception object, including exception type, message and stack trace information. This is very useful for debugging or log tracing

(2) e.getMessage(): just get the abnormal message information

Printing of abnormal information:

Use system Err printing and e.printStackTrace() are highlighted in red.

Use system Out print, print as ordinary information.

These two printing are two independent threads, and the order cannot be accurately controlled.

Chapter 10 multithreading

10.1 related concepts

1. Program

In order to realize a function and complete a task, a set of instructions written in a programming language is selected.

2. Process

A run of a program. The operating system allocates resources (memory) to the process.

Process is the smallest unit of resources allocated by the operating system.

The memory between processes is independent and cannot be shared directly.

The earliest DOS operating system was single task and could only run one process at a time. Later, the current operating systems support multitasking and can run multiple processes at the same time. Switch back and forth between processes. The cost is relatively high.

3. Thread

A thread is one of the execution paths in a process. A process can have at least one thread or multiple threads. Threads are sometimes referred to as lightweight processes.

Some memory can be shared among multiple threads of the same process (method area and heap), and some memory is independent (stack (including virtual machine stack and local method stack), program counter).

The cost of switching between threads is relatively low compared with the process.

4. Parallelism: multiple processors can execute multiple execution paths at the same time.

5. Concurrency: multiple tasks are executed at the same time, but there may be a sequence relationship.

10.2 two ways to realize multithreading

1. Inherit Thread class

Steps:

(1) Write a Thread class to inherit the Thread class

(2) Override public void run() {}

(3) Create thread object

(4) Call start()

class MyThread extends Thread {
    public void run(){
        //...
    }
}
class Test{
    public static void main(String[] args){
        MyThread my = new MyThread();
        my.start();//Thread object with name starts
        
        new MyThread().start();//Anonymous thread object start
        
        //Anonymous object startup of anonymous inner class
        new Thread(){
            public void run(){
                //...
            }
        }.start();
        
        //Anonymous internal class, but start the thread through the variable polymorphic reference of the parent class
        Thread t =  new Thread(){
            public void run(){
                //...
            }
        };
        t.start();
    }
}

2. Implement Runnable interface

Steps:

(1) Write a thread class to implement the Runnable interface

(2) Override public void run() {}

(3) Create thread object

(4) Start the Thread with the object of Thread class

class MyRunnable implements Runnable{
    public void run(){
        //...
    }
}
class Test {
    public static void main(String[] args){
        MyRunnable my = new MyRunnable();
        Thread t1 = new Thread(my);
        Thread t2 = new Thread(my);
        t1.start();
        t2.start();
        
        //Two anonymous objects
        new Thread(new MyRunnable()).start();
        
        //The anonymous object of the anonymous inner class is passed directly to the constructor of Thread as an argument
        new Thread(new Runnable(){
            public void run(){
                //...
            }
        }).start();
            
    }
}

10.3 thread life cycle

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-F11L5KKc-1623826110075)(imgs/1559782705811.png)]

10.4 related API of thread

1. Constructor

  • Thread()
  • Thread(String name)
  • Thread(Runnable target)
  • Thread(Runnable target, String name)

2. Other methods

(1)public void run()

(2)public void start()

(3) Get the current thread object: thread currentThread()

(4) Get the name of the current thread: getName()

(5) Set or get the priority of the thread: set/getPriority()

Priority range: [1,10], there are three constants in Thread class: MAX_PRIORITY(10),MIN_PRIORITY(1),NORM_PRIORITY(5)

Priority only affects probability.

(6) Thread sleep: thread Sleep (MS)

(7) Interrupt thread: interrupt()

(8) Pause current thread: thread yield()

(9) Thread to be plugged: join()

xx. The code of join () is written in which thread body and which thread is blocked, which has nothing to do with other threads.

(10) Determine whether the thread has started but not terminated: isAlive()

10.5 keyword: volatile

Volatile: volatile, unstable, not necessarily when

Modifiers: member variables

Function: when multiple threads access a member variable at the same time and frequently, if they find that its value has not been modified after multiple accesses, the Java execution engine will cache the value of this member variable. Once cached, if a thread changes the value of this member variable at this time, the Jav execution engine still reads it from the cache, resulting in the value being not up-to-date. If you don't want the Java execution engine to cache the value of this member variable, you can add volatile in front of the member variable. Every time you use this member variable, it is read from main memory.

10.6 keyword: synchronized

1. Under what circumstances can thread safety problems occur?

(1) Multiple threads

(2) Shared data

(3) In the thread body of multiple threads, when multiple statements operate the shared data again

2. How to solve thread safety problems? Synchronous lock

Form 1: synchronous code block

Form 2: synchronization method

3. Synchronous code block

synchronized(Lock object){
    //One time task code, in which the code does not want other threads to interfere in the execution process
}

Lock object:

(1) Any type of object

(2) Ensure that these threads that share data use the same lock object

4. Synchronization method

synchronized [Modifier] return value type method name([Formal parameter list])throws Exception list{
    //Only one thread can run at a time
}

Lock object:

(1) Non static method: this (cautious)

(2) Static method: the Class object of the current Class

10.7 thread communication

1. In order to solve the "producer and consumer problem".

When some threads are responsible for putting data into the "data buffer", another thread is responsible for fetching data from the "data buffer".

Question 1: producer threads and consumer threads use the same data buffer, that is, they share data, so synchronization should be considered

Question 2: when the data buffer is full, the producer thread needs to wait(). When the consumer consumes the data, it needs to notify or notifyAll

When the data buffer is empty, the consumer thread needs wait(). When the producer produces data, it needs notify or notifyAll

2,java.lang.Object class declares:

(1) wait(): must be called by the synchronization lock object

(2) Notify() and notifyAll(): must be called by the synchronization lock object

3. Interview question: the difference between sleep() and wait

(1) sleep() does not release the lock, wait() releases the lock

(2) sleep() is declared in the Thread class, and wait() is declared in the Object class

(3) Sleep () is a static method and thread sleep()

wait() is a non static method and must be called by the synchronization lock object

(4) After the sleep() method causes the current thread to enter the blocking state, when the time is up or interrupt() wakes up

After the wait() method causes the current thread to enter the blocking state, notify or notifyAll() is used

4. What actions release the lock?

(1) The lock is automatically released after the synchronization code block or synchronization method is normally executed once

(2) The synchronization code block or synchronization method ends prematurely when it encounters return

(3)wait()

5. Do not release the lock

(1)sleep()

(2)yield()

(3)suspend()

Chapter XI common categories

11.1 packaging

11.1.1 packaging

When you want to use API s or new features designed only for objects (such as generics), the data of basic data types needs to be wrapped with wrapper classes.

Serial numberBasic data typePackaging
1byteByte
2shortShort
3intInteger
4longLong
5floatFloat
6doubleDouble
7charCharacter
8booleanBoolean
9voidVoid

11.1.2 packing and unpacking

JDK1. After 5, it can automatically pack and unpack.

Note: automatic packing and unpacking can only be realized between the corresponding types.

Integer i = 1;
Double d = 1;//Wrong, 1 is of type int

Packing: convert the basic data type into a packing object.

Objects that are converted to wrapper classes are designed to use API s and features specifically designed for objects

Unpacking: unpacking packaging objects into basic data types.

The conversion to basic data type is generally due to the need for operation. Most operators in Java are designed for basic data types. Comparison, arithmetic, etc

Summary: what operators can be used for objects (reference data types)?

(1)instanceof

(2) =: assignment operator

(3) = = and! =: It is used to compare addresses, but the types of objects on the left and right sides must be the same or there is a parent-child class inheritance relationship.

(4) For special objects such as strings, "+" is supported to indicate splicing.

11.1.3 some API s for packaging

1. Conversion between basic data type and string

(1) Convert basic data type to string

int a = 10;
//String str = a;// FALSE
//Mode 1:
String str = a + "";
//Mode 2:
String str = String.valueOf(a);

(2) Convert string to basic data type

int a = Integer.parseInt("String of integers");
double a = Double.parseDouble("Decimal string");
boolean b = Boolean.parseBoolean("true or false");

2. Max min value of data type

Integer.MAX_VALUE and Integer.MIN_VALUE
Long.MAX_VALUE and Long.MIN_VALUE
Double.MAX_VALUE and Double.MIN_VALUE

3. Case conversion

Character.toUpperCase('x');
Character.toLowerCase('X');

4. Conversion system

Integer.toBinaryString(int i) 
Integer.toHexString(int i)
Integer.toOctalString(int i)

11.1.4 caching of wrapper objects

PackagingCache object
Byte-128~127
Short-128~127
Integer-128~127
Long-128~127
FloatNo,
DoubleNo,
Character0~127
Booleantrue and false
Integer i = 1;
Integer j = 1;
System.out.println(i == j);//true

Integer i = 128;
Integer j = 128;
System.out.println(i == j);//false

Integer i = new Integer(1);//The new is in the heap
Integer j = 1;//This uses a buffered constant object in the method area
System.out.println(i == j);//false

Integer i = new Integer(1);//The new is in the heap
Integer j = new Integer(1);//Another new one is in the heap
System.out.println(i == j);//false

Integer i = new Integer(1);
int j = 1;
System.out.println(i == j);//true, all comparisons with basic data types will be unpacked first and compared according to the rules of basic data types

11.2 string

11.2.1 characteristics of string

1. The String type itself is declared by final, which means that we cannot inherit String.

2. The object of the string is also an immutable object, which means that once it is modified, a new object will be generated

After we modify the string, if we want to get new content, we must accept it again.

If the program involves a large number of string modification operations, the time and space consumption is relatively high. You may need to consider using StringBuilder or StringBuffer.

3. String objects are stored internally in character arrays

JDK1. Before 9, there was a char[] value array, jdk1 byte [] array after 9

4. The char[] values array in the String class is also final modified, which means that the array is immutable, and then it is private modified. It cannot be operated directly by the outside. All the methods provided by the String type use new objects to represent the modified contents, so it ensures the immutability of the String object.

5. Because the string object is designed to be immutable, the string has a constant pool to hold many constant objects

The constant pool is in the method area.

If detailed division:

(1)JDK1.6 and before: method area

(2)JDK1.7: Pile

(3)JDK1.8: Meta space

11.2.2 comparison of string objects

1. = =: the address of the comparison object

true is returned only if both string variables are constant objects pointing to strings

String str1 = "hello";
String str2 = "hello";
str1 == str2//true

2. Equals: the comparison is the content of the object, because the String type overrides equals and is case sensitive

As long as the character contents of the two strings are the same, true will be returned

String str1 = new String("hello");
String str2 = new String("hello");
str1.equals(strs) //true

3. equalsIgnoreCase: compares the contents of an object and is not case sensitive

String str1 = new String("hello");
String str2 = new String("HELLO");
str1.equalsIgnoreCase(strs) //true

4. compareTo: the String type rewrites the abstract method of the Comparable interface. It is sorted naturally, and the size is compared according to the Unicode encoded value of the character. It is strictly case sensitive

String str1 = "hello";
String str2 = "world";
str1.compareTo(str2) //Values less than 0

5. compareToIgnoreCase: case insensitive. Compare the size of other characters according to the Unicode encoding value

String str1 = new String("hello");
String str2 = new String("HELLO");
str1.compareToIgnoreCase(str2)  //Equal to 0

11.2.3 comparison of empty characters

1. What are empty strings

String str1 = "";
String str2 = new String();
String str3 = new String("");

Empty string: length 0

2. How to determine whether a string is an empty string

if("".equals(str))

if(str!=null  && str.isEmpty())

if(str!=null && str.equals(""))

if(str!=null && str.length()==0)

11.2.4 number of string objects

1. String constant object

String str1 = "hello";//1 in constant pool

2. Normal object of string

String str2 = new String();
String str22 = new String("");
//Two objects, one is an empty string object in the constant pool and the other is an empty string object in the heap

3. The normal object of the string is used together with the constant object

String str3 = new String("hello");
//str3 first points to a string object in the heap, and then the value array of the string in the heap points to the value array of the constant object in the constant pool

11.2.5 string splicing results

principle:

(1) Constant + constant: the result is a constant pool

(2) Constants and variables or variables and variables: the result is heap

(3) call intern after splicing: the result is in constant pool.

	@Test
	public void test06(){
		String s1 = "hello";
		String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = (s1 + "world").intern();//Put the splicing results into the constant pool
		String s5 = (s1 + s2).intern();
		
		System.out.println(s3 == s4);//true
		System.out.println(s3 == s5);//true
	}
	
	@Test
	public void test05(){
		final String s1 = "hello";
		final String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = s1 + "world";//s4 string content is also helloworld, s1 is a constant, "world" constant, and the result of constant + constant is in the constant pool
		String s5 = s1 + s2;//s5 string contents are also helloworld. s1 and s2 are constants. The result of constant + constant is in the constant pool
		String s6 = "hello" + "world";//Constant + constant results are in the constant pool because the results can be determined during compilation
		
		System.out.println(s3 == s4);//true
		System.out.println(s3 == s5);//true
		System.out.println(s3 == s6);//true
	}
	
	@Test
	public void test04(){
		String s1 = "hello";
		String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = s1 + "world";//s4 string content is also helloworld, s1 is a variable, "world" constant, and the result of variable + constant is in the heap
		String s5 = s1 + s2;//s5 string content is also helloworld. s1 and s2 are variables. The result of variable + variable is in the heap
		String s6 = "hello" + "world";//Constant + constant results are in the constant pool because the results can be determined during compilation
		
		System.out.println(s3 == s4);//false
		System.out.println(s3 == s5);//false
		System.out.println(s3 == s6);//true
	}

11.2.6 string API

(1)boolean isEmpty()

(2)int length()

(3) String concat(xx): splicing, equivalent to+

(4)boolean contanis(xx)

(5) int indexOf(): find from front to back. If not, return - 1

(6) int lastIndexOf(): find from the back to the front. If not, return - 1

(7)char charAt(index)

(8) new String(char []) or new String(char [], int, int)

(9)char[] toCharArray()

(10) byte[] getBytes(): encoding, changing the string into a byte array and encoding according to the default character encoding of the platform

Byte [] GetBytes (character encoding method): encode according to the specified encoding method

(11) new String(byte []) or new String(byte[], int, int): decode according to the default character encoding of the platform

new String(byte [], character encoding method) or new String(byte[], int, int, character encoding method): decode according to the specified encoding method

(12) String subString(int begin): from [begin] to the end

String subString(int begin,int end): from [begin, end]

(13) Boolean matches (regular expressions)

(14) String replace(xx,xx): regular is not supported

String replacefirst (regular, value): replace the first matching part

String repalceall (regular, value): replace all matching parts

(15) String [] split (regular): split according to certain rules

(16) boolean startsWith(xx): whether it starts with xx

boolean endsWith(xx): whether to end with xx

(17) String trim(): remove the white space before and after the string, and the white space in the middle of the string will not be removed

(18) String toUpperCase(): convert to uppercase

(19) String toLowerCase(): convert to lowercase

Interview question: what is the difference between the length of a string and the length of an array?

length() of string, length attribute of array

11.3 variable character sequence

1. Variable character sequence: StringBuilder and StringBuffer

StringBuffer: old, thread safe (because its method is decorated with synchronized)

StringBuilder: thread unsafe

2. Interview question: what is the difference between String, StringBuilder and StringBuffer?

String: immutable object, immutable character sequence

StringBuilder, StringBuffer: variable character sequence

3. The common API s, StringBuilder and StringBuffer, are identical

(1) append(xx): splice, append

(2) insert(int index, xx): Insert

(3)delete(int start, int end)

deleteCharAt(int index)

(4)set(int index, xx)

(5) reverse(): reverse

... replace, intercept, find

11.4 mathematics related

1,java.lang.Math class

(1) sqrt(): find the square root

(2) pow(x,y): find the Y power of X

(3) random(): returns the decimal number in the [0,1) range

(4) max(x,y): find the maximum value of x,y

min(x,y): find the minimum value

(5) round(x): round

ceil(x): enter one

floor(x): back one

...

2,java.math package

BigInteger: large integer

BigDecimal: number of sizes

The operation is completed by the method: add(),subtract(),multiply(),divide()

11.5 date and time API

11.5.1 JDK1. Before 8

1,java.util.Date

new Date(): current system time

long getTime(): returns the millisecond value between 0.0.0 milliseconds from 1970-1-1 for the date time object

new Date(long millisecond): converts the millisecond value into a date time object

2,java.util.Calendar:

(1) getInstance(): get the tinning of Calendar

(2) Get (constant)

3,java.text.SimpleDateFormat: format of date and time

y: Indicate year

M: Month

d: Oh, my God

H: 24-hour system

h: 12 hour system

m: Divide

s: Seconds

S: Millisecond

E: Week

D: Number of days in the year

	@Test
	public void test10() throws ParseException{
		String str = "2019 Thursday, June 6, 2006 16:03:14.545 MS +0800";
		SimpleDateFormat sf = new SimpleDateFormat("yyyy year MM month dd day HH Time mm branch ss second SSS millisecond  E Z");
		Date d = sf.parse(str);
		System.out.println(d);
	}
	
	@Test
	public void test9(){
		Date d = new Date();

		SimpleDateFormat sf = new SimpleDateFormat("yyyy year MM month dd day HH Time mm branch ss second SSS millisecond  E Z");
		//Convert the Date into a string and convert it in the specified format
		String str = sf.format(d);
		System.out.println(str);
	}
	
	@Test
	public void test8(){
		String[] all = TimeZone.getAvailableIDs();
		for (int i = 0; i < all.length; i++) {
			System.out.println(all[i]);
		}
	}
	
	@Test
	public void test7(){
		TimeZone t = TimeZone.getTimeZone("America/Los_Angeles");
		
		//getInstance(TimeZone zone)
		Calendar c = Calendar.getInstance(t);
		System.out.println(c);
	}
	
	@Test
	public void test6(){
		Calendar c = Calendar.getInstance();
		System.out.println(c);
		
		int year = c.get(Calendar.YEAR);
		System.out.println(year);
		
		int month = c.get(Calendar.MONTH)+1;
		System.out.println(month);
		
		//...
	}
	
	@Test
	public void test5(){
		long time = Long.MAX_VALUE;
		Date d = new Date(time);
		System.out.println(d);
	}
	
	@Test
	public void test4(){
		long time = 1559807047979L;
		Date d = new Date(time);
		System.out.println(d);
	}
	@Test
	public void test3(){
		Date d = new Date();
		long time = d.getTime();
		System.out.println(time);//1559807047979
	}
	
	@Test
	public void test2(){
		long time = System.currentTimeMillis();
		System.out.println(time);//1559806982971
		//The time difference between the current system time and 1970-1-1 0:0:0 0 milliseconds, in milliseconds
	}
	
	@Test
	public void test1(){
		Date d = new Date();
		System.out.println(d);
	}

11.5.2 JDK1. After 8

java.time and its sub packages.

1,LocalDate,LocalTime,LocalDateTime

(1) now(): get the system date or time

(2) of(xxx): or the specified date or time

(3) Operation: a new object is obtained after operation and needs to be accepted again

plusXxx(): adds xx to the current date or time object

minusXxx(): subtract xx from the current date or time object

methoddescribe
now() / now(ZoneId zone)Static method to create an object based on the current time / an object with a specified time zone
of()Static method to create an object based on the specified date / time
getDayOfMonth()/getDayOfYear()Days of acquisition month (1-31) / days of acquisition year (1-366)
getDayOfWeek()Get the day of the week (return a DayOfWeek enumeration value)
getMonth()Get the Month and return a Month enumeration value
getMonthValue() / getYear()Acquisition month (1-12) / acquisition year
getHours()/getMinute()/getSecond()Obtain the hour, minute and second corresponding to the current object
withDayOfMonth()/withDayOfYear()/withMonth()/withYear()Modify the month days, year days, month and year to the specified value and return a new object
with(TemporalAdjuster t)Set the current date and time to the date and time specified by the proofreader
plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours()Add days, weeks, months, years, hours to the current object
minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours()Subtract months, weeks, days, years, hours from the current object
plus(TemporalAmount t)/minus(TemporalAmount t)Add or reduce a Duration or Period
isBefore()/isAfter()Compare two localdates
isLeapYear()Determine whether it is a leap year (declared in the LocalDate class)
format(DateTimeFormatter t)Format the local date and time, and return a string
parse(Charsequence text)Parses the string in the specified format into date and time

2. DateTimeFormatter: date and time formatting

This class provides three formatting methods:

Predefined standard formats. E.g. ISO_DATE_TIME;ISO_DATE

Localization related formats. For example: oflocalized date (formatstyle. Medium)

Custom format. For example: ofPattern("yyyy MM DD HH: mm: SS")

	@Test
	public void test10(){
		LocalDateTime now = LocalDateTime.now();
		
//		DateTimeFormatter df = DateTimeFormatter. ofLocalizedDateTime(FormatStyle.LONG);// June 6, 2019 04:40:03 PM
		DateTimeFormatter df = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);//19-6-6 4:40 pm
		String str = df.format(now);
		System.out.println(str);
	}
	@Test
	public void test9(){
		LocalDateTime now = LocalDateTime.now();
		
		DateTimeFormatter df = DateTimeFormatter.ISO_DATE_TIME;//2019-06-06T16:38:23.756
		String str = df.format(now);
		System.out.println(str);
	}
	
	@Test
	public void test8(){
		LocalDateTime now = LocalDateTime.now();
		
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy year MM month dd day HH Time mm branch ss second  SSS millisecond  E It's this year D day");
		String str = df.format(now);
		System.out.println(str);
	}
	
	@Test
	public void test7(){
		LocalDate now = LocalDate.now();
		LocalDate before = now.minusDays(100);
		System.out.println(before);//2019-02-26
	}
	
	@Test
	public void test06(){
		LocalDate lai = LocalDate.of(2019, 5, 13);
		LocalDate go = lai.plusDays(160);
		System.out.println(go);//2019-10-20
	}
	
	@Test
	public void test05(){
		LocalDate lai = LocalDate.of(2019, 5, 13);
		System.out.println(lai.getDayOfYear());
	}
	
	
	@Test
	public void test04(){
		LocalDate lai = LocalDate.of(2019, 5, 13);
		System.out.println(lai);
	}
	
	@Test
	public void test03(){
		LocalDateTime now = LocalDateTime.now();
		System.out.println(now);
	}
	
	@Test
	public void test02(){
		LocalTime now = LocalTime.now();
		System.out.println(now);
	}
	
	@Test
	public void test01(){
		LocalDate now = LocalDate.now();
		System.out.println(now);
	}

Chapter XII collection

12.1 concept

Data structure: a structure that stores data

(1) Underlying physical structure

① Array: open up continuous storage space, and each element is distinguished by [subscript]

② Chained: there is no need to open up a continuous storage space, but a "node" is needed to package the data to be stored. The node contains two parts:

A. data

B. record the addresses of other nodes, such as next, pre, left, right, parent, etc

(2) Logical structure: dynamic array, one-way linked list, two-way linked list, queue, stack, binary tree, hash table, graph, etc

12.2 manually implement some logical structures

1. Dynamic array

contain:

(1) An array is used internally to store data

(2) A total is used internally to record the number of elements actually stored

public class MyArrayList {
	//Why use Object? It's just that this container is used to hold objects, but I don't know what objects it is used to hold.
	private Object[] data;
	private int total;
	
	public MyArrayList(){
		data = new Object[5];
	}
	
	//Add an element
	public void add(Object obj){
		//Check whether capacity expansion is required
		checkCapacity();
		data[total++] = obj;
	}

	private void checkCapacity() {
		//If the data is full, the capacity will be doubled
		if(total >= data.length){
			data = Arrays.copyOf(data, data.length*2);
		}
	}
	
	//Returns the number of actual elements
	public int size(){
		return total;
	}
	
	//Returns the actual capacity of the array
	public int capacity(){
		return data.length;
	}
	
	//Get the element at [index] position
	public Object get(int index){
		//Check the rationality range of the index
		checkIndex(index);
		return data[index];
	}

	private void checkIndex(int index) {
		if(index<0 || index>=total){
			throw new RuntimeException(index+"The element at the corresponding position does not exist");
//			throw new IndexOutOfBoundsException(index + "out of bounds");
		}
	}
	
	//Replace the element at [index]
	public void set(int index, Object value){
		//Check the rationality range of the index
		checkIndex(index);
		
		data[index] = value;
	}
	
	//Insert an element value at [index]
	public void insert(int index, Object value){
		/*
		 * (1)Consider the rationality of subscript
		 * (2)Is the total length sufficient
		 * (3)[index]And the following elements move back to free up the [index] position
		 * (4)data[index]=value  Add new element
		 * (5)total++  The number of effective elements increases
		 */
		
		//(1) Consider the rationality of subscript: check the rationality range of index
		checkIndex(index);
		
		//(2) Whether the total length is enough: check whether the capacity needs to be expanded
		checkCapacity();
		
		//(3) Move the [index] and the following elements back to make room for the [index] position
		/*
		 * Suppose total = 5, data length= 10, index= 1
		 * Subscript of valid element [0,4]
		 * Move: [1] - [2], [2] - [3], [3] - [4], [4] - [5]
		 * Number of elements moved: total index
		 */
		System.arraycopy(data, index, data, index+1, total-index);
		
		//(4) Put data [index] = value into the new element
		data[index] = value;
		
		//(5) The number of total + + valid elements increases
		total++;
	}
	
	//Returns all the actually stored elements
	public Object[] getAll(){
		//Return total
		return Arrays.copyOf(data, total);
	}
	
	//Delete the element at [index]
	public void remove(int index){
		/*
		 * (1)Check the rationality range of the index
		 * (2)Move the element and move [index+1] and the following elements forward
		 * (3)Set data[total-1]=null and let the garbage collector recycle as soon as possible
		 * (4)total elements reduced--
		 */
		
		//(1) Consider the rationality of subscript: check the rationality range of index
		checkIndex(index);
		
		//(2) Move the element and move [index+1] and the following elements forward
		/*
		 * Suppose total = 8, data length=10, index = 3
		 * Range of valid elements [0,7]
		 * Move: [4] - [3], [5] - [4], [6] - [5], [7] - [6]
		 * Moved 4: total-index-1
		 */
		System.arraycopy(data, index+1, data, index, total-index-1);
		
		//(3) Set data[total-1]=null and let the garbage collector recycle as soon as possible
		data[total-1] = null;
		
//		(4) total elements reduced--
		total--;
	}
	
	//Query the subscript of an element
	public int indexOf(Object obj){
		if(obj == null){
			for (int i = 0; i < total; i++) {
				if(data[i] == null){//Equivalent to if(data[i] == obj)
					return i;
				}
			}
		}else{
			for (int i = 0; i < data.length; i++) {
				if(obj.equals(data[i])){
					return i;
				}
			}
		}
		return -1;
	}
	
	//Delete an element in the array
	//If there are duplicates, only the first one will be deleted
	public void remove(Object obj){
		/*
		 * (1)First query the [index] of obj
		 * (2)If it exists, call remove(index) to delete it
		 */
		
		//(1) First query the [index] of obj
		int index = indexOf(obj);
		
		if(index != -1){
			remove(index);
		}
		//It doesn't exist. You can do nothing
		//If it does not exist, you can throw exceptions
		//throw new RuntimeException(obj + "does not exist");
	}
	
	public void set(Object old, Object value){
		/*
		 * (1)Query [index] of old
		 * (2)If it exists, call set(index, value)
		 */
		
//		(1) Query [index] of old
		int index = indexOf(old);
		if(index!=-1){
			set(index, value);
		}
		
		//It doesn't exist. You can do nothing
	}
}

2. Unidirectional linked list

contain:

(1) Contains a Node type member variable first: used to record the address of the first Node

If the linked list is empty and there are no nodes, then first is null.

The feature of the last node is that its next is null

(2) A total is used internally to record the number of elements actually stored

(3) An internal class Node is used

private class Node{
    Object data;
    Node next;
}
public class SingleLinkedList {
	//There is no need for arrays or other complex structures. I just need to record the "head" node of the one-way linked list
	private Node first;//First records the address of the first node
	private int total;//Here I record total for the convenience of later processing. For example, when the user obtains the number of effective elements in the linked list, he does not need to present the number, but directly returns total, etc
	
	/*
	 * Internal class, because this type of Node node is useless elsewhere. It is only used in the one-way linked list to store and represent its Node relationship.
	 * Because I'm dealing with internal types here.
	 */
	private class Node{
		Object data;//Because data can be any type of Object, it is designed as Object
		Node next;//Because the address of the next node is recorded in next, the type is the node type
		//Here, data and next are not privatized. It is hoped that get/set is not required in the external class, but can be directly used by "node object. Data" and "node object. Next"
		Node(Object data, Node next){
			this.data = data;
			this.next = next;
		}
	}
	
	public void add(Object obj){
		/*
		 * (1)Wrap obj data into a Node object of Node type
		 * (2)Link the new node to the end of the current linked list
		 * ①The current new node is the first node
		 * How to determine whether it is the first if(first==null) indicates that there is no first one yet
		 * ②First find the last one and link the new node to its next
		 * How to judge whether it is the last if (a node. next == null) indicates that this node is the last
		 */
//		(1) Wrap obj data into a Node object of Node type
		//Here, the next value of the new node is null, indicating that the new node is the last node
		Node newNode = new Node(obj, null);
		
		//① The current new node is the first node
		if(first == null){
			//Description newNode is the first
			first = newNode;
		}else{
			//② First find the last one and link the new node to its next
			Node node = first;
			while(node.next != null){
				node = node.next;
			}
			//When exiting the loop, the node points to the last node
			
			//Link the new node to its next
			node.next = newNode;
		}
		
		total++;
	}
	
	public int size(){
		return total;
	}
	
	public Object[] getAll(){
		//(1) Create an array with the length of total
		Object[] all = new Object[total];
		
		//(2) Take the data in each node of the one-way linked list and put it into the all array
		Node node = first;
		for (int i = 0; i < total; i++) {
//			all[i] = node data;
			all[i] = node.data;
			//Then point to the next node
			node = node.next;
		}
		
		//(3) Return array
		return all;
	}
	
	public void remove(Object obj){
		if(obj == null){
			//(1) First consider whether it is the first one
			if(first!=null){//Linked list is not empty
				
				//The node to be deleted is exactly the first node
				if(first.data == null){
					//Let the first node point to its next node
					first = first.next;
					total--;
					return;
				}
				
				//The node to be deleted is not the first node
				Node node = first.next;//Second node
				Node last = first;
				while(node.next!=null){//The last one is not included here because node Next = = null, does not enter the loop, but node Next = = null is the last one
					if(node.data == null){
						last.next = node.next;
						total--;
						return;
					}
					last = node;
					node = node.next;
				}
				
				//Judge whether the last node is the node to be deleted
				if(node.data == null){
					//The last node to be deleted
					last.next = null;
					total--;
					return;
				}
			}
		}else{
			//(1) First consider whether it is the first one
			if(first!=null){//Linked list is not empty
				
				//The node to be deleted is exactly the first node
				if(obj.equals(first.data)){
					//Let the first node point to its next node
					first = first.next;
					total--;
					return;
				}
				
				//The node to be deleted is not the first node
				Node node = first.next;//Second node
				Node last = first;
				while(node.next!=null){//The last one is not included here because node Next = = null, does not enter the loop, but node Next = = null is the last one
					if(obj.equals(node.data)){
						last.next = node.next;
						total--;
						return;
					}
					last = node;
					node = node.next;
				}
				
				//Judge whether the last node is the node to be deleted
				if(obj.equals(node.data)){
					//The last node to be deleted
					last.next = null;
					total--;
					return;
				}
			}
		}
	}

	public int indexOf(Object obj){
		if(obj == null){
			Node node = first;
			for (int i = 0; i < total; i++) {
				if(node.data == null){
					return i;
				}
				node = node.next;
			}
		}else{
			Node node = first;
			for (int i = 0; i < total; i++) {
				if(obj.equals(node.data)){
					return i;
				}
				node = node.next;
			}
		}
		return -1;
	}
}

12.3 Collection

Because there are many types of collections, we call them collection frameworks.

The collection framework is divided into two families: Collection (a set of objects) and Map (a set of mapping relationships and a set of key value pairs)

12.3.1 Collection

A Collection is a Collection that represents an object. It is the root interface of the Collection family.

Although some of them may be ordered, some may be disordered, some may be repeatable, and some cannot be repeated, they have common operation specifications, so the specifications of these operations are abstracted as the Collection interface.

Common methods:

(1) boolean add(Object obj): add a

(2) boolean addAll (Collection c): add multiple

(3) boolean remove(Object obj): deletes an object

(4) boolean removeAll(Collection c): delete multiple

(5) boolean contains(Object c): whether to include a

(6) boolean containsAll(Collection c): whether to include all

(7) boolean isEmpty(): is it empty

(8) int size(): get the number of elements

(9) void clear(): clear the collection

(10) Object[] toArray(): get all elements

(11) Iterator iterator(): gets the iterator object that traverses the current collection

(12) Retain all (collection c): find the intersection of the current set and the c set

12.3.2 traversal of Collection Series

1. Explicitly use Iterator iterators

Collection c = ....;

Iterator iter = c.iterator();
while(iter.hashNext()){
    Object obj = iter.next();
    //...
}

Methods of Iterator interface:

(1)boolean hasNext()

(2)Object next()

(3)void remove()

2,foreach

Collection c = ....;

for(Object  obj :  c){
    //...
}

What kind of collection (container) can be traversed by foreach?

(1) Array:

(2) Implemented Java Lang. Iterable interface

This interface has an abstract method: Iterator iterator()

Iterator is also an interface. Its implementation class is usually implemented by internal classes in collection (container) classes. And create its object in the method of iterator().

public class MyArrayList implements Iterable{
	//Why use Object? It's just that this container is used to hold objects, but I don't know what objects it is used to hold.
	private Object[] data;
	private int total;
	
	//Other codes are omitted

	@Override
	public Iterator iterator() {
		return new MyItr();
	}
	
	private class MyItr implements Iterator{
		private int cursor;//cursor

		@Override
		public boolean hasNext() {
			return cursor!=total;
		}

		@Override
		public Object next() {
			return data[cursor++];
		}
	}
}

Thinking: if you traverse an array, under what circumstances do you choose foreach and for loop?

When your operation involves [subscript] operation, it is best to use for.

When you just look at the content of the element, choose foreach to be more concise.

Thinking: if you traverse the Collection series, under what circumstances do you choose foreach and whether you can choose for loop?

First, consider using foreach. If the set also has index information, you can also operate through for. If there is no subscript information, don't use for. That is, if the physical structure of the set is array, you can use for. If the physical structure is chain, the operation efficiency of using subscript is very low.

Thinking: if you traverse the Collection series, under what circumstances do you choose foreach and Iterator?

If you just look at the elements of the collection, the code will be more concise by using foreach.

However, if it involves operations such as deleting elements according to certain conditions while traversing the collection, Iterator is selected.

12.4 List

12.4.1 List overview

List: is the sub interface of Collection.

A collection of List series: ordered and repeatable

Common collections of List series: ArrayList, Vector, LinkedList, Stack

12.4.2 API of list

Common methods:

(1) boolean add(Object obj): add a

(2) boolean addAll (Collection c): add multiple

(3) void add(int index, Object obj): add one at a specified location

(4) void addAll(int index, Collection c): add multiple

(5) boolean remove(Object obj): deletes an object

(6) Object remove(int index): deletes the element at the specified position and returns the element just deleted

(7) boolean removeAll(Collection c): delete multiple

(8) boolean contains(Object c): whether to include a

(9) boolean containsAll(Collection c): whether to include all

(10) boolean isEmpty(): is it empty

(11) int size(): get the number of elements

(12) void clear(): clear the collection

(13) Object[] toArray(): get all elements

(14) Iterator iterator(): gets the iterator object that traverses the current collection

(15) Retain all (collection c): find the intersection of the current set and the c set

(16) ListIterator listIterator(): get the iterator object that traverses the current collection. This iterator can traverse forward and backward

(17) ListIterator listIterator(int index): traverse forward or backward from the [index] position

(18) Object get(int index): returns the element at the index position

(19) List subList(int start, int end): intercept the sublist of the [start,end) part

12.4.3 ListIterator interface

Methods of Iterator interface:

(1)boolean hasNext()

(2)Object next()

(3)void remove()

ListIterator is a sub interface of Iterator: the following methods are added

(4)void add(Object obj)

(5)void set(Object obj)

(6)boolean hasPrevious()

(7)Object previous()

(8)int nextIndex()

(9)int previousIndex()

12.4.4 differences between list implementation classes

ArrayList,Vector,LinkedList,Stack

(1) ArrayList and Vector: both are dynamic arrays

Vector is the earliest version of dynamic array. It is thread safe. The default capacity expansion mechanism is 2 times. It supports the iterator Enumeration of the old version

ArrayList is a dynamic array added later. The thread is unsafe. The default capacity expansion mechanism is 1.5 times

(2) The difference between dynamic array and LinkedList

Dynamic array: the underlying physical structure is an array

Advantage: fast access according to [subscript]

Disadvantages: need to open up continuous storage space, and need to expand capacity, move elements and other operations

LinkedList: the underlying physical structure is a two-way linked list

Advantages: when adding or deleting elements, you do not need to move the elements, but only need to modify the reference relationship between the front and rear elements

Disadvantages: when looking for elements, we can only start from first or last

(3) Stack: stack

Is a subclass of Vector. There are several more methods than Vector, which can show the characteristics of "first in, last out or last in, first out".

① Object peek(): access stack top element

② Object pop(): pop up stack top element

③ push(): push elements to the top of the stack

(4) LinkedList can be used as a variety of data structures

Single linked list: just focus on next

Queue: first in, first out, find the corresponding method

Double ended queue (joined by JDK1.6): both ends can enter and exit. Find the corresponding method

Stack: first in, last out, find the corresponding method

Suggestion: Although LinkedList supports index operation because it implements all methods of the List interface, we don't recommend calling methods like this because of its low efficiency.

12.4.5 source code analysis

(1)Vector

    public Vector() {
        this(10);//Specify an initial capacity of 10
    }
	public Vector(int initialCapacity) {
        this(initialCapacity, 0);//Specify a capacityIncrement increment of 0
    }
    public Vector(int initialCapacity, int capacityIncrement Increment is 0) {
        super();
        //The validity of the initial capacity of the formal parameter initialCapacity is judged
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        //Created an array of type Object []
        this.elementData = new Object[initialCapacity];//The default is 10
        //Increment, the default is 0. If it is 0, it will be increased by 2 times later. If it is not 0, it will be increased by the increment you specify later
        this.capacityIncrement = capacityIncrement;
    }
//synchronized means thread safe   
	public synchronized boolean add(E e) {
        modCount++;
    	//See if capacity expansion is needed
        ensureCapacityHelper(elementCount + 1);
    	//Store the new element in [elementCount]. After saving, the number of elementCount elements will increase by 1
        elementData[elementCount++] = e;
        return true;
    }

    private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        //See if the capacity of the current array is exceeded
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);//Capacity expansion
    }
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//Gets the length of the current array
        //If the capacity increment is 0, the new capacity = 2 times the oldCapacity
        //If the capacityIncrement increment is 0, the new capacity = oldCapacity + capacityIncrement increment;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        
        //If the new capacity calculated above is not enough, expand the minCapacity according to the minimum capacity you specify
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        
        //If the new capacity exceeds the maximum array limit, it is processed separately
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        
        //Copy the data from the old array to the new array. The length of the new array is newCapacity
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    public boolean remove(Object o) {
        return removeElement(o);
    }
    public synchronized boolean removeElement(Object obj) {
        modCount++;
        //Find the subscript of obj in the current Vector
        int i = indexOf(obj);
        //If I > = 0, it indicates that it exists. Delete the element at [i]
        if (i >= 0) {
            removeElementAt(i);
            return true;
        }
        return false;
    }
    public int indexOf(Object o) {
        return indexOf(o, 0);
    }
    public synchronized int indexOf(Object o, int index) {
        if (o == null) {//The element to find is a null value
            for (int i = index ; i < elementCount ; i++)
                if (elementData[i]==null)//If it is a null value, use = = null to judge
                    return i;
        } else {//The element to find is a non null value
            for (int i = index ; i < elementCount ; i++)
                if (o.equals(elementData[i]))//If it is a non null value, use equals to judge
                    return i;
        }
        return -1;
    }
    public synchronized void removeElementAt(int index) {
        modCount++;
        //Judge the legitimacy of subscript
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        else if (index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        
        //j is the number of elements to be moved
        int j = elementCount - index - 1;
        //If you need to move elements, call system Arraycopy to move
        if (j > 0) {
            //Move the index+1 position and the following elements forward
            //Move the element at the position of index+1 to the position of index, and so on
            //Move j in total
            System.arraycopy(elementData, index + 1, elementData, index, j);
        }
        //The total number of elements decreased
        elementCount--;
        //Empty the location of elementData[elementCount] to add new elements. The elements in the location are waiting to be recycled by GC
        elementData[elementCount] = null; /* to let gc do its work */
    }

(2) ArrayList source code analysis

JDK1.6:

    public ArrayList() {
		this(10);//Specify an initial capacity of 10
    }
    public ArrayList(int initialCapacity) {
		super();
        //Check the legitimacy of the initial capacity
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        //The array is initialized to an array of length initialCapacity
		this.elementData = new Object[initialCapacity];
    }

JDK1.7

    private static final int DEFAULT_CAPACITY = 10;//Default initial capacity 10
	private static final Object[] EMPTY_ELEMENTDATA = {};
	public ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;//The array is initialized to an empty array
    }
    public boolean add(E e) {
        //Check whether the current array has enough more than one element
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {//If the current array is still empty
            //minCapacity is processed according to the default initial capacity and the maximum value in minCapacity
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
		//See if capacity expansion is needed
        ensureExplicitCapacity(minCapacity);
    }
	//...

JDK1.8

private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//Initialize to empty array
    }
    public boolean add(E e) {
        //Check whether the current array has enough more than one element
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        
        //Save the new element to the [size] position, and then increase the size by 1
        elementData[size++] = e;
        return true;
    }
    private void ensureCapacityInternal(int minCapacity) {
        //If the current array is still empty
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //Then minCapacity takes default_ Maximum value of capacity and minCapacity
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
		//Check whether capacity expansion is required
        ensureExplicitCapacity(minCapacity);
    }
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;//Number of modifications plus 1

        // If the required minimum capacity is larger than the length of the current array, that is, the current array is not enough, expand the capacity
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//Current array capacity
        int newCapacity = oldCapacity + (oldCapacity >> 1);//The capacity of the new array is 1.5 times that of the old array
        //See if 1.5 times of the old array is enough
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //See if the 1.5 times of the old array exceeds the maximum array limit
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        
        //Copy a new array
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    public boolean remove(Object o) {
        //First find o the subscript in the array of the current ArrayList
        //Discuss whether o is empty or not
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {//null values are compared with = =
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {//Non null values are compared with equals
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
    private void fastRemove(int index) {
        modCount++;//Number of modifications plus 1
        //Number of elements to be moved
        int numMoved = size - index - 1;
        
        //If you need to move elements, use system Arraycopy move element
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        
        //Empty the elementData[size-1] position to allow GC to reclaim space and reduce the number of elements
        elementData[--size] = null; // clear to let GC do its work
    }
    public E remove(int index) {
        rangeCheck(index);//Check whether the index is legal

        modCount++;//Number of modifications plus 1
        
        //Take out the element at [index]. The element at [index] is the element to be deleted, which is used to return the deleted element finally
        E oldValue = elementData(index);
        
		//Number of elements to be moved
        int numMoved = size - index - 1;
        
        //If you need to move elements, use system Arraycopy move element
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        //Empty the elementData[size-1] position to allow GC to reclaim space and reduce the number of elements
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }
    public E set(int index, E element) {
        rangeCheck(index);//Check whether the index is legal

        //Take out the element at [index]. The element at [index] is the element to be replaced, which is used to return the replaced element finally
        E oldValue = elementData(index);
        //Replace the element at [index] with element
        elementData[index] = element;
        return oldValue;
    }
    public E get(int index) {
        rangeCheck(index);//Check whether the index is legal

        return elementData(index);//Returns the element at the [index] position
    }
    public int indexOf(Object o) {
        //There are two cases: o is empty or not
        if (o == null) {
            //Look from front to back
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }
    public int lastIndexOf(Object o) {
         //There are two cases: o is empty or not
        if (o == null) {
            //Look back and forward
            for (int i = size-1; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = size-1; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

(3) LinkedList source code analysis

int size = 0;
Node<E> first;//Record the position of the first node
Node<E> last;//Record the position of the last node

    private static class Node<E> {
        E item;//Element data
        Node<E> next;//Next node
        Node<E> prev;//Previous node

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    public boolean add(E e) {
        linkLast(e);//By default, the new element is linked to the end of the linked list
        return true;
    }
    void linkLast(E e) {
        final Node<E> l = last;//Record the original last node with l
        
        //Create a new node
        final Node<E> newNode = new Node<>(l, e, null);
        //Now the new node is the last node
        last = newNode;
        
        //If l==null, the original linked list is empty
        if (l == null)
            //Then the new node is also the first node
            first = newNode;
        else
            //Otherwise, link the new node to the next of the original last node
            l.next = newNode;
        //Increase in the number of elements
        size++;
        //Increase in modification times
        modCount++;
    }
    public boolean remove(Object o) {
        //There are two situations: whether o is empty or not
        if (o == null) {
            //Find the node x corresponding to o
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);//Delete x node
                    return true;
                }
            }
        } else {
            //Find the node x corresponding to o
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);//Delete x node
                    return true;
                }
            }
        }
        return false;
    }
    E unlink(Node<E> x) {//x is the node to be deleted
        // assert x != null;
        final E element = x.item;//Data of deleted node
        final Node<E> next = x.next;//The next node of the deleted node
        final Node<E> prev = x.prev;//The previous node of the deleted node

        //If there is no node in front of the deleted node, it means that the deleted node is the first node
        if (prev == null) {
            //Then the next node of the deleted node becomes the first node
            first = next;
        } else {//The deleted node is not the first node
            //The next of the previous node of the deleted node points to the next node of the deleted node
            prev.next = next;
            //Disconnect the link between the deleted node and the previous node
            x.prev = null;//Make GC recycle
        }

        //If there is no node after the deleted node, it means that the deleted node is the last node
        if (next == null) {
            //Then the previous node of the deleted node becomes the last node
            last = prev;
        } else {//The deleted node is not the last node
            //The prev of the next node of the deleted node executes the previous node of the deleted node
            next.prev = prev;
            //Disconnect the deleted node from the next node
            x.next = null;//Make GC recycle
        }
		//The data of the deleted node is also set to be empty to make GC recycle
        x.item = null;
        //Decrease in the number of elements
        size--;
        //Increase in modification times
        modCount++;
        //Returns the data of the deleted node
        return element;
    }

12.5 Set

12.5.1 Set overview

Set of set series: non repeatable

Set series of sets, both ordered and disordered. HashSet is out of order. TreeSet traverses according to the size order of elements, and LinkedHashSet traverses according to the addition order of elements.

12.5.2 characteristics of implementation class

(1)HashSet:

The bottom layer is the HashMap implementation. The element added to the HashSet is the key of the HashMap, and value is a constant Object of type Object PRESENT.

The hashCode() and equals() that depend on the element ensure the non repetition of the element. The storage location is related to the hashCode() value. Calculate its [index] in the underlying table array according to the hashCode()

(2)TreeSet

The bottom layer is the implementation of TreeMap. The element added to TreeSet is the key of TreeMap, and value is a constant Object PRESENT of Object type.

Depending on the size of the element, either Java Lang. comparable interface compareTo(Object obj), or Java util. compare(Object o1, Object o2) of the comparator interface to compare the size of elements. Two elements of equal size are considered to be repeating elements.

(3)LinkedHashSet

The bottom layer is LinkedHashMap. The element added to the LinkedHashSet is the key of the LinkedHashMap, and value is a constant Object PRESENT of type Object.

LinkedHashSet is a subclass of HashSet, which maintains the addition order of elements more than the parent class.

Use it if and only if you want elements to be non repeatable and ensure the order in which they are added.

12.6 Map

12.6.1 Map overview

Used to store key value pairs, a collection of mapping relationships. All Map keys cannot be duplicate.

Type of key value pair and mapping relationship: Entry type

Entry Interface is Map Internal interface of the interface. be-all Map All types of key value pairs implement this interface.
HashMap There is an internal class to implement the mapping relationship in Entry The interface of, JDK1.7 It's a man called Entry Internal class implementation of Entry Interface.
JDK1.8 It's a man called Node Internal class implementation of Entry Interface.
TreeMap The mapping relationship in has an internal class Entry To achieve Entry Interface of

12.6.2 API

(1) put(Object key, Object value): add a pair of mapping relationships

(2) putAll(Map m): add a multi pair mapping relationship

(3) clear(): clear the map

(4) remove(Object key): deletes a pair according to the key

(5) int size(): get the logarithm of valid elements

(6) containsKey(Object key): whether to include a key

(7) containsValue(Object value): whether to include a value

(8) Object get(Object key): get value according to the key

(9) Several methods of traversal

Collection values(): get all values for traversal

Set keySet(): get all keys for traversal

Set entrySet(): get all mapping relationships for traversal

12.6.3 differences between map implementation classes

(1)HashMap:

Ensure whether the key is repeated according to the hashCode() and equals() of the key.

If the key is repeated, the new value will replace the old value.

Hashcode () determines the storage location of the mapping relationship in the table array. Index = hash (key. hashCode()) & table length-1

The underlying implementation of HashMap: jdk1 7 is array + linked list; JDK1.8 is array + linked list / red black tree

(2)TreeMap

Ensure whether the key is repeated according to the size of the key. If the key is repeated, the new value will replace the old value.

The size of the key depends on Java Lang. comparable or Java util. Comparator.

(3)LinkedHashMap

Ensure whether the key is repeated according to the hashCode() and equals() of the key. If the key is repeated, the new value will replace the old value.

LinkedHashMap is a subclass of HashMap and has more addition order than HashMap

12.6.4 HashMap source code analysis

JDK1.6 source code:

    public HashMap() {
        //this.loadFactor is a loading factor that affects the frequency of capacity expansion
        //DEFAULT_LOAD_FACTOR: the default loading factor is 0.75
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        //threshold = capacity * loading factor
        //Threshold: when the size reaches threshold, capacity expansion is considered
        //Capacity expansion requires two conditions to be met at the same time: (1) size > = thread (2) table[index]= null, that is, the location where the new mapping relationship is to be stored is not empty
        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
        //table is an array,
        //DEFAULT_ INITIAL_ Capability: 16 by default
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        init();
    }

JDK1.7 source code:

    public HashMap() {
    	//DEFAULT_ INITIAL_ Capability: default initial capacity 16
    	//DEFAULT_LOAD_FACTOR: the default loading factor is 0.75
        this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
    }
    public HashMap(int initialCapacity, float loadFactor) {
        //Verify the validity of initialCapacity
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
        //Verify the validity of initialCapacity (initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        //Verify the legitimacy of loadFactor
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
		//Load factor, initialized to 0.75
        this.loadFactor = loadFactor;
        // threshold is the initial capacity                                  
        threshold = initialCapacity;
        init();
    }
public V put(K key, V value) {
        //If the table array is empty, create the array first
        if (table == EMPTY_TABLE) {
            //threshold is initially the value of the initial capacity
            inflateTable(threshold);
        }
        //If the key is null, handle it separately
        if (key == null)
            return putForNullKey(value);
        
        //Interfere with the hashCode of the key and calculate a hash value
        int hash = hash(key);
        
        //The calculated new mapping relationship should be saved to table[i],
        //i = hash & table. Length-1, which can ensure that I is within the range of [0,table.length-1]
        int i = indexFor(hash, table.length);
        
        //Check whether the key under table[i] duplicates the key of my new mapping relationship. If so, replace value
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        //Add a new mapping relationship
        addEntry(hash, key, value, i);
        return null;
    }
    private void inflateTable(int toSize) {
        // Find a power of 2 >= toSize
        int capacity = roundUpToPowerOf2(toSize);//The capacity is equal to the nearest n-th power of 2 of the toSize value
		//Calculation threshold = capacity * loading factor
        threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
        //Create an Entry [] array with a length of capacity
        table = new Entry[capacity];
        initHashSeedAsNeeded(capacity);
    }
	//If the key is null, it is directly stored in the location of [0]
    private V putForNullKey(V value) {
        //Judge whether there are duplicate key s. If there are duplicates, replace value
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {
            if (e.key == null) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        modCount++;
        //Store the new mapping relationship in the position of [0], and the hash value of the key is represented by 0
        addEntry(0, null, value, 0);
        return null;
    }
    void addEntry(int hash, K key, V value, int bucketIndex) {
        //Judge whether storage capacity is required
        //Capacity expansion: (1) size reaches the threshold (2) table[i] is not empty
        if ((size >= threshold) && (null != table[bucketIndex])) {
            //The capacity of the table is doubled, and after the capacity expansion, the storage locations of all mapping relationships will be readjusted
            resize(2 * table.length);
            //The hash and index of the new mapping relationship will also be recalculated
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }
		//Save in table
        createEntry(hash, key, value, bucketIndex);
    }
    void createEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
        //The mapping relationship under the original table[i] is used as the new mapping relationship next
        table[bucketIndex] = new Entry<>(hash, key, value, e);
        size++;//Increase in number
    }

1,put(key,value)

(1) When the mapping relationship is added for the first time, the array is initialized to a * * HashMap with a length of 16 E n t r y ∗ ∗ of number group , this individual H a s h M a p An array of Entry * *, this HashMap The HashMapEntry type implements Java util. Map. Entry interface

(2) Special consideration: if the key is null, the index is directly [0]

(3) Before calculating the index, the hashCode() value of the key will be hashed again, which can make the Entry object more hashed and stored in the table

(4) Calculate index = table length-1 & hash;

(5) If the key of the existing mapping relationship under table[index] is the same as the key of the new mapping relationship I want to add, the old value will be replaced with the new value.

(6) If not, the new mapping relationship will be added to the header of the linked list, and the Entry object under the original table[index] will be connected to the next of the new mapping relationship.

(7) Judge if (size > = threshold & & table [index]! = null) before adding. If the condition is true, the capacity will be expanded

​ if(size >= threshold && table[index]!=null){

① capacity expansion

② the hash of the key will be recalculated

③ the index will be recalculated

​ }

2,get(key)

(1) Calculate the hash value of the key. Use this method to hash(key)

(2) Find index = table length-1 & hash;

(3) If table[index] is not empty, the key of which Entry is the same as it will be compared one by one, and its value will be returned

3,remove(key)

(1) Calculate the hash value of the key. Use this method to hash(key)

(2) Find index = table length-1 & hash;

(3) If the table[index] is not empty, compare which Entry has the same key one by one, delete it, and change the value of the next of the Entry in front of it to the next of the deleted Entry

JDK1.8 source code

Several constants and variables:
(1)DEFAULT_INITIAL_CAPACITY: Default initial capacity 16
(2)MAXIMUM_CAPACITY: Maximum capacity 1 << 30
(3)DEFAULT_LOAD_FACTOR: Default load factor 0.75
(4)TREEIFY_THRESHOLD: The default treelization threshold is 8. When the length of the linked list reaches this value, treelization should be considered
(5)UNTREEIFY_THRESHOLD: The default anti tree threshold is 6. When the number of nodes in the tree reaches this threshold, it should be considered to become a linked list
(6)MIN_TREEIFY_CAPACITY: Minimum tree capacity 64
		When the number of nodes in a single linked list reaches 8, and table Only when the length reaches 64 can it be trealized.
		When the number of nodes in a single linked list reaches 8, but table If the length of does not reach 64, the capacity will be expanded first
(7)Node<K,V>[] table: array
(8)size: Record the logarithm of the effective mapping relationship, too Entry Number of objects
(9)int threshold: Threshold, when size Consider capacity expansion when the threshold is reached
(10)double loadFactor: The loading factor affects the frequency of capacity expansion
    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; 
        // All other fields are defaulted
    }
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
	//Purpose: to interfere with hashCode value
    static final int hash(Object key) {
        int h;
		//If the key is null, the hash is 0
		//If the key is not null, use the hashCode value of the key to XOR with the hashCode value of the key higher than 16
		//		That is, the high 16 bits and low 16 bits of the hashCode value of the key are used for XOR interference operation
		
		/*
		index = hash & table.length-1
		If you use the original hashCode value of key and table If length-1 performs bitwise and, then basically high 16 has no chance to use it.
		This will increase the probability of conflict. In order to reduce the probability of conflict, the high 16 bits are added to the hash information.
		*/
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
        Node<K,V>[] tab; //array
		Node<K,V> p; //One node
		int n, i;//n is the length of the array and i is the subscript
		
		//tab and table are equivalent
		//If table is empty
        if ((tab = table) == null || (n = tab.length) == 0){
            n = (tab = resize()).length;
            /*
			tab = resize();
			n = tab.length;*/
			/*
			If the table is empty, resize() completes ① creating an array with a length of 16 ② threshold = 12
			n = 16
			*/
        }
		//I = (n - 1) & hash, subscript = array length - 1 & hash
		//p = tab[i] 1st node
		//if(p==null) condition is satisfied, it means that table[i] has no element
		if ((p = tab[i = (n - 1) & hash]) == null){
			//Put the new mapping relationship directly into table[i]
            tab[i] = newNode(hash, key, value, null);
			//The newNode () method creates a new Node of Node type, and the next of the new Node is null
        }else {
            Node<K,V> e; 
			K k;
			//p is the first node in table[i]
			//If (the first node of table [i] duplicates the key of the new mapping relationship)
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k)))){
                e = p;//Use e to record the first node of this table[i]
			}else if (p instanceof TreeNode){//If the first node of table[i] is a tree node
                //Handle tree nodes separately
                //If there is a duplicate key in the tree node, return the duplicate node and receive it with E, that is, e= null
                //If there is no duplicate key in the tree node, put the new node into the tree and return null, that is, e=null
				e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            }else {
				//The first node of table[i] is not a tree node, nor does it duplicate the key of the new mapping relationship
				//binCount records the number of nodes under table[i]
                for (int binCount = 0; ; ++binCount) {
					//If the next node of P is empty, it means that the current p is the last node
                    if ((e = p.next) == null) {
						//Connect the new node to the end of table[i]
                        p.next = newNode(hash, key, value, null);
						
						//If bincount > = 8-1, when it reaches 7
                        if (binCount >= TREEIFY_THRESHOLD - 1){ // -1 for 1st
                            //Either expand or tree
							treeifyBin(tab, hash);
						}
                        break;
                    }
					//If the key is repeated, it will jump out of the for loop. At this time, node e records the node with the repeated key
            if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k)))){
                        break;
					}
                    p = e;//The next cycle, e=p.next, is similar to e=e.next, moving down the linked list
                }
            }
			//If this e is not null, it indicates that there is a duplicate key. Consider replacing the original value
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null){
                    e.value = value;
				}
                afterNodeAccess(e);//Nothing
                return oldValue;
            }
        }
        ++modCount;
		
		//Increase in the number of elements
		//size reached threshold
        if (++size > threshold){
            resize();//Once the capacity is expanded, readjust the position of all mapping relationships
		}
        afterNodeInsertion(evict);//Nothing
        return null;
    }	
	
   final Node<K,V>[] resize() {
        Node<K,V>[] oldTab = table;//oldTab original table
		//oldCap: the length of the original array
        int oldCap = (oldTab == null) ? 0 : oldTab.length;
		
		//oldThr: original threshold
        int oldThr = threshold;//The initial threshold is 0
		
		//newCap, new capacity
		//newThr: new threshold
        int newCap, newThr = 0;
        if (oldCap > 0) {//Description: the original array is not empty
            if (oldCap >= MAXIMUM_CAPACITY) {//Whether the maximum limit of the array is reached
                threshold = Integer.MAX_VALUE;
                return oldTab;
            }else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                     oldCap >= DEFAULT_INITIAL_CAPACITY){
				//newCap = old capacity * 2, new capacity < maximum array capacity limit
				//New capacity: 32,64
				//Oldcap > = initial capacity 16
				//New threshold recalculation = 24, 48
                newThr = oldThr << 1; // double threshold
			}
        }else if (oldThr > 0){ // initial capacity was placed in threshold
            newCap = oldThr;
        }else {               // zero initial threshold signifies using defaults
            newCap = DEFAULT_INITIAL_CAPACITY;//The new capacity is the default initialization capacity of 16
			//New threshold = Default loading factor * default initialization capacity = 0.75 * 16 = 12
            newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
        }
        if (newThr == 0) {
            float ft = (float)newCap * loadFactor;
            newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
                      (int)ft : Integer.MAX_VALUE);
        }
        threshold = newThr;//The threshold value is assigned to the new threshold value 12, 24...
		
		//A new array with the length of newCap, 16, 32, 64. Is created..
        @SuppressWarnings({"rawtypes","unchecked"})
            Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
        table = newTab;
		
		
        if (oldTab != null) {//It's not an empty array
			//Invert the mapping relationship from the original table to the new table
            for (int j = 0; j < oldCap; ++j) {
                Node<K,V> e;
                if ((e = oldTab[j]) != null) {//e is the node under the table
                    oldTab[j] = null;//Empty the old table[j] position
                    if (e.next == null)//If it is the last node
                        newTab[e.hash & (newCap - 1)] = e;//Recalculate the storage location of e in the new table and put it into
                    else if (e instanceof TreeNode)//If e is a tree node
						//Disassemble the original tree and put it into a new table
                        ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
                    else { // preserve order
                        Node<K,V> loHead = null, loTail = null;
                        Node<K,V> hiHead = null, hiTail = null;
                        Node<K,V> next;
						/*
						Move the entire linked list under the original table[i] to the new table
						*/
                        do {
                            next = e.next;
                            if ((e.hash & oldCap) == 0) {
                                if (loTail == null)
                                    loHead = e;
                                else
                                    loTail.next = e;
                                loTail = e;
                            }
                            else {
                                if (hiTail == null)
                                    hiHead = e;
                                else
                                    hiTail.next = e;
                                hiTail = e;
                            }
                        } while ((e = next) != null);
                        if (loTail != null) {
                            loTail.next = null;
                            newTab[j] = loHead;
                        }
                        if (hiTail != null) {
                            hiTail.next = null;
                            newTab[j + oldCap] = hiHead;
                        }
                    }
                }
            }
        }
        return newTab;
    }	
	
    Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) {
		//Create a new node
	   return new Node<>(hash, key, value, next);
    }

    final void treeifyBin(Node<K,V>[] tab, int hash) {
        int n, index; 
		Node<K,V> e;
		//MIN_ TREEIFY_ Capability: minimum tree capacity 64
		//If the table is empty or the length of the table does not reach 64
        if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
            resize();//Expand capacity first
        else if ((e = tab[index = (n - 1) & hash]) != null) {
			//Use e to record the address of the node of table[index]
            TreeNode<K,V> hd = null, tl = null;
			/*
			do...while,Change the Node node of the table[index] linked list into a TreeNode type Node
			*/
            do {
                TreeNode<K,V> p = replacementTreeNode(e, null);
                if (tl == null)
                    hd = p;//hd record root node
                else {
                    p.prev = tl;
                    tl.next = p;
                }
                tl = p;
            } while ((e = e.next) != null);
			
            //If the table[index] is not empty
            if ((tab[index] = hd) != null)
                hd.treeify(tab);//Tree the linked list under table[index]
        }
    }	

1. Add process

(1) When the mapping relationship is added for the first time, the array is initialized to a * * HashMap with a length of 16 N o d e ∗ ∗ of number group , this individual H a s h M a p Array of Node * *, this HashMap The HashMapNode type implements Java util. Map. Entry interface

(2) Before calculating the index, the hashCode() value of the key will be hashed again, which can make the Entry object more hashed and stored in the table

JDK1.8. The implementation of hash(key) method is better than jdk1 7 be concise. key. hashCode() ^ key. Code()>>>16;

(3) Calculate index = table length-1 & hash;

(4) If the key of the existing mapping relationship under table[index] is the same as the key of the new mapping relationship I want to add, the old value will be replaced with the new value.

(5) If you don't have the same,

① table[index] if the length of the linked list does not reach 8, the new mapping relationship will be added to the tail of the linked list

② table[index] the length of the linked list reaches 8, but the table If the length does not reach 64, the table will be expanded first and then added

③ table[index] the length of the linked list reaches 8, and the table When the length reaches 64, the branch will be treed first, the node type will be changed to TreeNode, and then the linked list will be transformed into a red black tree

④ table[index] is already a red black tree, so if you are directly connected to the tree, you may also consider left-hand and right-hand rotation to ensure the balance of the tree

(6) Judge if after adding (size > threshold){

① capacity expansion

② the hash of the key will be recalculated

③ the index will be recalculated

​ }

2,remove(key)

(1) Calculate the hash value of the key. Use this method to hash(key)

(2) Find index = table length-1 & hash;

(3) If the table[index] is not empty, compare which Entry has the same key one by one, delete it, and change the value of the next of the Entry in front of it to the next of the deleted Entry

(4) If there is a red black tree under the table[index], and the number of nodes is less than or equal to 6 after deletion, the red black tree will be changed into a linked list

12.6.5 interview questions about HashMap

1. The underlying implementation of HashMap

Answer: jdk1 7 is array + linked list, jdk1 8 is array + linked list / red black tree

2. Element type of HashMap's array

Answer: Java util. Map $entry interface type.

JDK1. The HashMap of 7 has an internal class Entry to implement the Entry interface

JDK1. There are internal classes Node and TreeNode types in the HashMap of 8 to implement the Entry interface

3. Why use arrays?

A: because the access efficiency of array is high

4. Why do arrays need linked lists? Or how to resolve hash or [index] conflicts?

A: to solve the conflict between hash and [index]

(1) The hashCode value of two different key s may be the same

(2) For two keys with different hashcodes, use hash(key) and hash & table The [index] obtained by length-1 operation may be the same

This means that the mapping relationship objects of multiple entries may need to be stored under table[index], so a linked list is required

5. Initialization length of HashMap array

A: the default initial capacity value is 16

6. How to calculate the storage index of the mapping relationship of HashMap

Answer: hash & table length-1

7. Why use hashCode()? Space for time

A: because hashCode() is an integer value, it can be used to directly calculate the index, which is more efficient. Although using array structure will waste some space, it can improve the query efficiency.

8. What is the function of hash()

A: before calculating the index, the hashCode() value of the key will be hashed again. This can make the Entry object more hashed and stored in the table

JDK1.8. The implementation of hash(key) method is better than jdk1 7 be concise. key. hashCode() ^ key. Code()>>>16; Because this can make the high 16 bit information of hashcode participate in the operation

9. Why must the array length of HashMap be to the power of 2

A: because the binary value of the nth power of 2-1 is 0 in the front and 1 in the back. In this way, the result of & operation with hash can be guaranteed to be within the range of [0,table.length-1] and uniform.

10. Why does HashMap use & bitwise and instead of% modulo?

Answer: because & efficiency is high

11. When will the HashMap array be expanded?

Answer: jdk1 Version 7: when adding a new Entry object, it is found that (1) the size reaches the threshold (2) table [index]= When null, the capacity will be expanded if the two conditions are met at the same time

JDK1. Version 8: when adding a new Entry object, it is found that (1) the size reaches the threshold (2) when the number of nodes under table[index] reaches 8, but the table The length did not reach 64. Meeting one of the two conditions will lead to the expansion of the array

Moreover, once the array is expanded, no matter which version, it will cause all mapping relationships to readjust the storage location.

12. How to calculate the expansion threshold (critical value)?

A: threshold = capacity * loadactor

13. Why is loadFactor 0.75? If it is 1 or 0.1, what is the difference?

Answer: 1. The number of nodes under a table[index] may be very long

0.1 will cause the frequency of array expansion to be too high

14,JDK1. When will the HashMap of 8 become a tree?

A: when the number of nodes under table[index] reaches 8, but table Length has reached 64

15,JDK1. When will HashMap of 8 be de treed?

A: when the number of tree nodes under table[index] is less than 6

16,JDK1. Why should 8's HashMap be treelized?

A: because when the number of nodes under table[index] exceeds 8, the query efficiency is low. If it is modified to red black tree, the query efficiency can be improved

17,JDK1. Why should 8's HashMap be de treed?

A: because when the number of nodes in the tree under table[index] is less than 6, the use of red black tree is too complicated. At this time, the use of linked list is simple and efficient

18. What are the requirements for overriding the equals and hashCode methods as the key type of HashMap

(1) equals and hashCode are rewritten together

(2) Rewrite the equals() method, but there are some precautions;

  • Reflexivity: x.equals(x) must return true.
    Symmetry: the return values of x.equals(y) and y.equals(x) must be equal.
    Transitivity: if x.equals(y) is true and y.equals(z) is also true, then x.equals(z) must be true.
    Consistency: if the information used by objects X and Y in equals() does not change, the x.equals(y) value remains unchanged.
    Non null: if x is not null and Y is null, x.equals(y) must be false.

(3) precautions for rewriting hashCode()

  • If equals returns two objects that are true, the hashCode value must be the same, and the hashCode value cannot be modified as long as the attribute participating in equals judgment is not modified;
    If equals returns two objects that are false, the hashCode value can be the same or different;
    If the hashCode values are different, equals must return false;
    hashCode should not be too simple, too simple will lead to serious conflicts, and hashCode should not be too complex, which will lead to low performance;

19. Why do most hashcode methods use 31?

A: because 31 is a prime number

20. Can I modify the object attribute of the key that has been stored in the HashMap? Why?

Answer: if this attribute is involved in hashCode calculation, do not modify it. Because once the hashCode() is modified, it is no longer the original value.
When stored in HashMap, the hashCode() – > hash () – > hash of the key has been determined and will not be recalculated. When the new hashCode value is used to query get(key) / remove(key), the calculated hash value is different from the original, so the original mapping relationship cannot be found.

21. Why, in our actual development, the type of key is generally String and Integer

A: because they are immutable.

22. Why do hash variables and key variables of Node or Entry type in HashMap add final declaration?

A: because I don't want you to modify the hash and key values

23. Why should the Node or Entry type in HashMap store hash separately?

A: in order to improve the efficiency of hash comparison in the process of adding, deleting and searching, it is not necessary to recalculate the hash value of key every time

24. Can the object attribute of value stored in HashMap be modified? Why?

A: Yes. Because we store, delete, etc. according to the key, which has nothing to do with value.

25. If the key is null, how is it stored?

A: it will exist in table[0]

12.7 assembly frame diagram

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-0H7wXmzt-1623826110078)(imgs/1560348912361.png)]

Chapter 13 generics

13.1 overview of generics

Generics: parameterized types

Type parameter:,,,,,....

Type argument: must be a reference data type, not a basic data type

​ ,,,<ArrayList>. . .

13.2 form 1: generic class and generic interface

1. Declaration syntax format:

[Modifier] class Class name/Interface<Type parameter list>{
    
}

[Modifier] class Class name/Interface<Type parameter 1 extends Upper limit of parent class>{
    
}
[Modifier] class Class name/Interface<Type parameter 1 extends Upper limit of parent class & Upper limit of parent interface>{
    
}

The generic parameter type declared after the class name or interface name can be used in the current class or interface to declare member variables, formal parameters of methods and return values of methods.

But it cannot be used on static members

2. Use syntax format

(1) specify specific types for generic parameters when creating objects of generic classes and generic interfaces

(2) specify specific types for generic parameters when inheriting generic classes or implementing generic interfaces

Sample code

ArrayList<String> list = new ArrayList<String>();

ArrayList<String> list = new ArrayList<>();//JDK1. It can be omitted after 7

class MyStringArrayList extends ArrayList<String>{
    
}

class Employee implements Comparable<Employee>{
    public int compareTo(Employee e){
        
    }
}

Arrays.sort(array,  new  Comparator<Generic argument>(){
    public int compare(Generic argument type  o1, Generic argument type  o2){
        
    }
});

3. If a generic type is not specified, it will be erased and processed according to the leftmost upper limit. If no upper limit is specified, it will be processed according to Object

13.3 form 2: generic method

1. Syntax format of declaration

[Modifier] <Generic parameter list>  Return value type method name([[data parameter list])[throws [exception list]{}
[Modifier] <Generic parameter extends Upper limit of parent class & Upper limit of parent interface>  Return value type method name([[data parameter list])[throws [exception list]{}

(1) The generic parameter type declared before the method return value type can only be used in the current method. It is used to represent the type of parameter or return value type, or the type of method local variable, which has nothing to do with other methods.

(2) Generic methods can be static or non static

2. Use

When the method is called, the type of generic argument will be determined according to the type of argument of specific data.

13.4 wildcard?

(1)?: Represents any reference data type

(2)? Extensions upper limit: represents the upper limit itself or its subclass

(3)? super lower limit: represents the lower limit itself or its parent class

For example:

ArrayList<?>: Indicates that any type is acceptable

ArrayList<?> list = new ArrayList<String>();
ArrayList<?> list = new ArrayList<Integer>();
ArrayList<?> list = new ArrayList<Animal>();

ArrayList<? Extensions upper limit >:

ArrayList<? extends Person> list = new ArrayList<Person>();
ArrayList<? extends Person> list = new ArrayList<Animal>();//Animal can't, because animal is the parent class
ArrayList<? extends Person> list = new ArrayList<Student>();
ArrayList<? extends Person> list = new ArrayList<Dog>();//Neither can Dog

ArrayList<? Super lower limit >:

ArrayList<? super Person> list = new ArrayList<Person>();
ArrayList<? super Person> list = new ArrayList<Animal>();
ArrayList<? super Person> list = new ArrayList<Student>();//Student, because student is a subclass
ArrayList<? super Person> list = new ArrayList<Dog>();//Neither can Dog

ArrayList<?>: Cannot add element except null

ArrayList<? Extensions upper limit >: cannot add elements except null

ArrayList<? Super lower limit >: you can add objects of lower limit or lower limit subclass

13.5 Collections tool class

java.util.Collections: tool class, operation collection

(1)public static boolean addAll(Collection<? super T> c, T... elements)

Add several objects of elements to the c Collection. T is the type of elements object. It is required that the element type of Collection collection must be t or the parent class of T

(2)public static int binarySearch(List<? extends Comparable<? super T>> list,T key)

Use dichotomy to find the subscript of key in the list set. If there is a reasonable subscript, if there is no subscript, it is a negative subscript

T is the type of element,

<? extends Comparable<? Super T > >, which requires that the elements of the collection must implement the comparable interface <? Super T >, when implementing the comparable interface, you can specify the comparable < type argument > as the parent class of T or t. (3)public static boolean disjoint(Collection<?> c1, Collection<?> c2)

It is true if c1 and c2 do not intersect

(4)public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)

Find the largest element in the coll set

<T extends Object & Comparable<? Super T > >: the parent class of T or T is required to implement the compatible interface

Because you need to compare the size to find the maximum value

(5)public static <T extends Comparable<? Super T > > void sort (list) sorts the list set

<T extends Comparable<? Super T > >: the parent class of T or T is required to implement the compatible interface

(6)public static Collection synchronizedCollection(Collection c)

Methods starting with synchronizedXX indicate that a non thread safe collection is transformed into a thread safe collection.

(7)public static List unmodifiableList(List<? extends T> list)

Methods that begin with unmodifiableXx return a "read-only" collection.

Chapter 18 design mode

18.1 formwork design mode (understand)

1. When solving a problem or completing a function, the algorithm structure (steps) of the main body is determined, but one or several small steps are uncertain. When users (subclasses) need to determine, the template design pattern can be used

2. Example code: calculate the running time of any piece of code

//template class
public abstract class CalTime{
    public long getTime(){
        //1. Get start time
        long start =  System.currentTimeMills();
        
        //2. Run xx Code: This is uncertain
        doWork();
        
        //3. Get end time
        long end =  System.currentTimeMills();
        
        //4. Calculate time difference
        return end - start;
    }
    
    protected abstract void doWork();
}

Use template class:

public class MyCalTime extends CalTime{
    protected void doWork(){
        //.... Code that needs to calculate run time
    }
}

Test class

public class Test{
    public static void main(String[] args){
        MyCalTime my = new MyCalTime();
        System.out.println("Running time:" + my.getTime());
    }
}

18.2 single case design mode

Single example: there is only one object of a certain type in the whole system.

1. Hungry Han style

(1) Enumerative

public enum Single{
    INSTANCE
}

(2) Form II

public class Single{
    public static final Single INSTANCE = new Single();
    private Single(){
        
    }
}

(3) Form III

public class Single{
    private static final Single INSTANCE = new Single();
    private Single(){
        
    }
    public static Single getInstance(){
        return INSTANCE;
    }
}

2. Lazy style

(1) Internal class form

public class Single{
    private Single(){}
    
    private static class Inner{
        static final Single INSTANCE = new Single();
    }
    
    public static Single getInstance(){
        return Inner.INSTANCE;
    }
    
}

(2) Form II

public class Single{
    private static Single instance;
    private Single(){}
    
    public static Single getInstance(){
        if(instance == null){
            synchronized(Single.class){
                if(instance == null){
                    instance = new Single();
                }
            }
        }
        return instance;
    }
}

3. Why use arrays?

A: because the access efficiency of array is high

4. Why do arrays need linked lists? Or how to resolve hash or [index] conflicts?

A: to solve the conflict between hash and [index]

(1) The hashCode value of two different key s may be the same

(2) For two keys with different hashcodes, use hash(key) and hash & table The [index] obtained by length-1 operation may be the same

This means that the mapping relationship objects of multiple entries may need to be stored under table[index], so a linked list is required

5. Initialization length of HashMap array

A: the default initial capacity value is 16

6. How to calculate the storage index of the mapping relationship of HashMap

Answer: hash & table length-1

7. Why use hashCode()? Space for time

A: because hashCode() is an integer value, it can be used to directly calculate the index, which is more efficient. Although using array structure will waste some space, it can improve the query efficiency.

8. What is the function of hash()

A: before calculating the index, the hashCode() value of the key will be hashed again. This can make the Entry object more hashed and stored in the table

JDK1.8. The implementation of hash(key) method is better than jdk1 7 be concise. key. hashCode() ^ key. Code()>>>16; Because this can make the high 16 bit information of hashcode participate in the operation

9. Why must the array length of HashMap be to the power of 2

A: because the binary value of the nth power of 2-1 is 0 in the front and 1 in the back. In this way, the result of & operation with hash can be guaranteed to be within the range of [0,table.length-1] and uniform.

10. Why does HashMap use & bitwise and instead of% modulo?

Answer: because & efficiency is high

11. When will the HashMap array be expanded?

Answer: jdk1 Version 7: when adding a new Entry object, it is found that (1) the size reaches the threshold (2) table [index]= When null, the capacity will be expanded if the two conditions are met at the same time

JDK1. Version 8: when adding a new Entry object, it is found that (1) the size reaches the threshold (2) when the number of nodes under table[index] reaches 8, but the table The length did not reach 64. Meeting one of the two conditions will lead to the expansion of the array

Moreover, once the array is expanded, no matter which version, it will cause all mapping relationships to readjust the storage location.

12. How to calculate the expansion threshold (critical value)?

A: threshold = capacity * loadactor

13. Why is loadFactor 0.75? If it is 1 or 0.1, what is the difference?

Answer: 1. The number of nodes under a table[index] may be very long

0.1 will cause the frequency of array expansion to be too high

14,JDK1. When will the HashMap of 8 become a tree?

A: when the number of nodes under table[index] reaches 8, but table Length has reached 64

15,JDK1. When will HashMap of 8 be de treed?

A: when the number of tree nodes under table[index] is less than 6

16,JDK1. Why should 8's HashMap be treelized?

A: because when the number of nodes under table[index] exceeds 8, the query efficiency is low. If it is modified to red black tree, the query efficiency can be improved

17,JDK1. Why should 8's HashMap be de treed?

A: because when the number of nodes in the tree under table[index] is less than 6, the use of red black tree is too complicated. At this time, the use of linked list is simple and efficient

18. What are the requirements for overriding the equals and hashCode methods as the key type of HashMap

(1) equals and hashCode are rewritten together

(2) Rewrite the equals() method, but there are some precautions;

  • Reflexivity: x.equals(x) must return true.
    Symmetry: the return values of x.equals(y) and y.equals(x) must be equal.
    Transitivity: if x.equals(y) is true and y.equals(z) is also true, then x.equals(z) must be true.
    Consistency: if the information used by objects X and Y in equals() does not change, the x.equals(y) value remains unchanged.
    Non null: if x is not null and Y is null, x.equals(y) must be false.

(3) precautions for rewriting hashCode()

  • If equals returns two objects that are true, the hashCode value must be the same, and the hashCode value cannot be modified as long as the attribute participating in equals judgment is not modified;
    If equals returns two objects that are false, the hashCode value can be the same or different;
    If the hashCode values are different, equals must return false;
    hashCode should not be too simple, too simple will lead to serious conflicts, and hashCode should not be too complex, which will lead to low performance;

19. Why do most hashcode methods use 31?

A: because 31 is a prime number

20. Can I modify the object attribute of the key that has been stored in the HashMap? Why?

Answer: if this attribute is involved in hashCode calculation, do not modify it. Because once the hashCode() is modified, it is no longer the original value.
When stored in HashMap, the hashCode() – > hash () – > hash of the key has been determined and will not be recalculated. When the new hashCode value is used to query get(key) / remove(key), the calculated hash value is different from the original, so the original mapping relationship cannot be found.

21. Why, in our actual development, the type of key is generally String and Integer

A: because they are immutable.

22. Why do hash variables and key variables of Node or Entry type in HashMap add final declaration?

A: because I don't want you to modify the hash and key values

23. Why should the Node or Entry type in HashMap store hash separately?

A: in order to improve the efficiency of hash comparison in the process of adding, deleting and searching, it is not necessary to recalculate the hash value of key every time

24. Can the object attribute of value stored in HashMap be modified? Why?

A: Yes. Because we store, delete, etc. according to the key, which has nothing to do with value.

25. If the key is null, how is it stored?

A: it will exist in table[0]

12.7 assembly frame diagram

[external chain picture transferring... (img-0H7wXmzt-1623826110078)]

Chapter 13 generics

13.1 overview of generics

Generics: parameterized types

Type parameter:,,,,,....

Type argument: must be a reference data type, not a basic data type

​ ,,,<ArrayList>. . .

13.2 form 1: generic class and generic interface

1. Declaration syntax format:

[Modifier] class Class name/Interface<Type parameter list>{
    
}

[Modifier] class Class name/Interface<Type parameter 1 extends Upper limit of parent class>{
    
}
[Modifier] class Class name/Interface<Type parameter 1 extends Upper limit of parent class & Upper limit of parent interface>{
    
}

The generic parameter type declared after the class name or interface name can be used in the current class or interface to declare member variables, formal parameters of methods and return values of methods.

But it cannot be used on static members

2. Use syntax format

(1) specify specific types for generic parameters when creating objects of generic classes and generic interfaces

(2) specify specific types for generic parameters when inheriting generic classes or implementing generic interfaces

Sample code

ArrayList<String> list = new ArrayList<String>();

ArrayList<String> list = new ArrayList<>();//JDK1. It can be omitted after 7

class MyStringArrayList extends ArrayList<String>{
    
}

class Employee implements Comparable<Employee>{
    public int compareTo(Employee e){
        
    }
}

Arrays.sort(array,  new  Comparator<Generic argument>(){
    public int compare(Generic argument type  o1, Generic argument type  o2){
        
    }
});

3. If a generic type is not specified, it will be erased and processed according to the leftmost upper limit. If no upper limit is specified, it will be processed according to Object

13.3 form 2: generic method

1. Syntax format of declaration

[Modifier] <Generic parameter list>  Return value type method name([[data parameter list])[throws [exception list]{}
[Modifier] <Generic parameter extends Upper limit of parent class & Upper limit of parent interface>  Return value type method name([[data parameter list])[throws [exception list]{}

(1) The generic parameter type declared before the method return value type can only be used in the current method. It is used to represent the type of parameter or return value type, or the type of method local variable, which has nothing to do with other methods.

(2) Generic methods can be static or non static

2. Use

When the method is called, the type of generic argument will be determined according to the type of argument of specific data.

13.4 wildcard?

(1)?: Represents any reference data type

(2)? Extensions upper limit: represents the upper limit itself or its subclass

(3)? super lower limit: represents the lower limit itself or its parent class

For example:

ArrayList<?>: Indicates that any type is acceptable

ArrayList<?> list = new ArrayList<String>();
ArrayList<?> list = new ArrayList<Integer>();
ArrayList<?> list = new ArrayList<Animal>();

ArrayList<? Extensions upper limit >:

ArrayList<? extends Person> list = new ArrayList<Person>();
ArrayList<? extends Person> list = new ArrayList<Animal>();//Animal can't, because animal is the parent class
ArrayList<? extends Person> list = new ArrayList<Student>();
ArrayList<? extends Person> list = new ArrayList<Dog>();//Neither can Dog

ArrayList<? Super lower limit >:

ArrayList<? super Person> list = new ArrayList<Person>();
ArrayList<? super Person> list = new ArrayList<Animal>();
ArrayList<? super Person> list = new ArrayList<Student>();//Student, because student is a subclass
ArrayList<? super Person> list = new ArrayList<Dog>();//Neither can Dog

ArrayList<?>: Cannot add element except null

ArrayList<? Extensions upper limit >: cannot add elements except null

ArrayList<? Super lower limit >: you can add objects of lower limit or lower limit subclass

13.5 Collections tool class

java.util.Collections: tool class, operation collection

(1)public static boolean addAll(Collection<? super T> c, T... elements)

Add several objects of elements to the c Collection. T is the type of elements object. It is required that the element type of Collection collection must be t or the parent class of T

(2)public static int binarySearch(List<? extends Comparable<? super T>> list,T key)

Use dichotomy to find the subscript of key in the list set. If there is a reasonable subscript, if there is no subscript, it is a negative subscript

T is the type of element,

<? extends Comparable<? Super T > >, which requires that the elements of the collection must implement the comparable interface <? Super T >, when implementing the comparable interface, you can specify the comparable < type argument > as the parent class of T or t. (3)public static boolean disjoint(Collection<?> c1, Collection<?> c2)

It is true if c1 and c2 do not intersect

(4)public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)

Find the largest element in the coll set

<T extends Object & Comparable<? Super T > >: the parent class of T or T is required to implement the compatible interface

Because you need to compare the size to find the maximum value

(5)public static <T extends Comparable<? Super T > > void sort (list) sorts the list set

<T extends Comparable<? Super T > >: the parent class of T or T is required to implement the compatible interface

(6)public static Collection synchronizedCollection(Collection c)

Methods starting with synchronizedXX indicate that a non thread safe collection is transformed into a thread safe collection.

(7)public static List unmodifiableList(List<? extends T> list)

Methods that begin with unmodifiableXx return a "read-only" collection.

Chapter 18 design mode

18.1 formwork design mode (understand)

1. When solving a problem or completing a function, the algorithm structure (steps) of the main body is determined, but one or several small steps are uncertain. When users (subclasses) need to determine, the template design pattern can be used

2. Example code: calculate the running time of any piece of code

//template class
public abstract class CalTime{
    public long getTime(){
        //1. Get start time
        long start =  System.currentTimeMills();
        
        //2. Run xx Code: This is uncertain
        doWork();
        
        //3. Get end time
        long end =  System.currentTimeMills();
        
        //4. Calculate time difference
        return end - start;
    }
    
    protected abstract void doWork();
}

Use template class:

public class MyCalTime extends CalTime{
    protected void doWork(){
        //.... Code that needs to calculate run time
    }
}

Test class

public class Test{
    public static void main(String[] args){
        MyCalTime my = new MyCalTime();
        System.out.println("Running time:" + my.getTime());
    }
}

18.2 single case design mode

Single example: there is only one object of a certain type in the whole system.

1. Hungry Han style

(1) Enumerative

public enum Single{
    INSTANCE
}

(2) Form II

public class Single{
    public static final Single INSTANCE = new Single();
    private Single(){
        
    }
}

(3) Form III

public class Single{
    private static final Single INSTANCE = new Single();
    private Single(){
        
    }
    public static Single getInstance(){
        return INSTANCE;
    }
}

2. Lazy style

(1) Internal class form

public class Single{
    private Single(){}
    
    private static class Inner{
        static final Single INSTANCE = new Single();
    }
    
    public static Single getInstance(){
        return Inner.INSTANCE;
    }
    
}

(2) Form II

public class Single{
    private static Single instance;
    private Single(){}
    
    public static Single getInstance(){
        if(instance == null){
            synchronized(Single.class){
                if(instance == null){
                    instance = new Single();
                }
            }
        }
        return instance;
    }
}

Topics: Java