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 category | This package | Subclasses of other packages | Any 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 number | Basic data type | Packaging |
---|---|---|
1 | byte | Byte |
2 | short | Short |
3 | int | Integer |
4 | long | Long |
5 | float | Float |
6 | double | Double |
7 | char | Character |
8 | boolean | Boolean |
9 | void | Void |
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
Packaging | Cache object |
---|---|
Byte | -128~127 |
Short | -128~127 |
Integer | -128~127 |
Long | -128~127 |
Float | No, |
Double | No, |
Character | 0~127 |
Boolean | true 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
method | describe |
---|---|
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; } }