Singleton mode
Hungry Han Trilogy (waste of resources)
1. privatize the constructor (so that the external cannot directly new your class instance)
private GirlFriend(String name) { this.name = name; }
2. create directly within the class (create a girlfriend of your own in your own class)
private static GirlFriend gf = new GirlFriend("Red red");
3. provide a static public method to return the gf object (the static keyword is the premise)
public static GirlFriend getInstance(){ return gf; }
Total code (the external cannot create new or create multiple objects, and the external can only get the method that returns the girlfriend object through this class call)
public class single { public static void main(String[] args) { GirlFriend instance = GirlFriend.getInstance(); System.out.println(instance); } } //There is a class, GirlFriend //Only one girlfriend class GirlFriend{ private String name; //In order to return gf objects in static methods, modify them to static private static GirlFriend gf = new GirlFriend("Red red"); //Only one GirlFriend object can be created //step //1. privatize the constructor //2. create directly within the class //3. provide a static public method to return gf object private GirlFriend(String name) { this.name = name; } public static GirlFriend getInstance(){ return gf; } @Override public String toString() { return "GirlFriend{" + "name='" + name + '\'' + '}'; } }
Lazy Trilogy (thread unsafe)
1. constructor privatization
private Cat(String name) { this.name = name; }
2. define a static attribute object
private static Cat cat;
3. provide a public static method that can return a Cat object (in the case of multiple threads, multiple threads simultaneously new Cat, resulting in unsafe threads, can also return an object)
public static Cat getInstance(){ if (cat == null){//If the cat object is not created cat = new Cat("Cutie"); } return cat; }
4. lazy. Only when the user uses getInstance, the cat object will be returned. When calling again, the last created cat object will be returned (they will reuse the existing object and are too lazy to create it)
Total code
public class single2 { public static void main(String[] args) { Cat instance = Cat.getInstance(); System.out.println(instance); } } //It is hoped that only one cat can be created while the program is running //Use singleton mode class Cat{ private String name; private static Cat cat; //step //1. constructor privatization //2. define a static attribute object //3. provide a public static method to return a Cat object //4. lazy. Only when the user uses getInstance, the cat object will be returned. When calling again, the last created cat object will be returned //Guaranteed monotonicity private Cat(String name) { this.name = name; } public static Cat getInstance(){ if (cat == null){//If the cat object is not created cat = new Cat("Cutie"); } return cat; } @Override public String toString() { return "Cat{" + "name='" + name + '\'' + '}'; } }
Exception -exception
First knowledge of exception code
(abnormal mathematical operation)
public static void main(String[] args) { int num1 = 10; int num2 = 0; int res = num1 / num2; System.out.println("Program continues...."); }
Solution - exception capture (try catch)
Catch exceptions to ensure that the program can continue to run (exception handling mechanism)
public static void main(String[] args) { int num1 = 10; int num2 = 0; //1. num1 / num2 => 10 / 0 //2. when executing to num1 / num2, because num2 = 0, the program will throw an exception ArithmeticException //3. when an exception is thrown, the program will exit and crash, and the following code will not be executed //4. can you think of such a procedure? No, there shouldn't be a non fatal problem that would cause the whole system to crash //5. java designers provide an exception handling mechanism to solve this problem // int res = num1 / num2; //If a programmer thinks that an exception may occur in a piece of code, he can use the try catch exception handling mechanism to solve it //So as to ensure the robustness of the program //Select the code block - > Select - > shortcut Ctrl + Alt + T - > select try catch //6. if exception handling is performed, the program can continue to execute even if an exception occurs try { int res = num1 / num2; } catch (Exception e) { //e.printStackTrace(); System.out.println("Cause of abnormality=" + e.getMessage()); //Output exception information} System.out.println("Program continues...."); } }
Error and Exception
Anomaly system diagram
Common runtime exceptions
\1) NullPointerException null pointer exception
\2) ArithmeticException mathematical operation exception
\3) ArrayIndexOutOfBoundsException array index out of bounds exception
\4) ClassCastException type conversion exception
\5) NumberFormatException incorrect number format exception []
\1)NullPointerException null pointer exception
public static void main(String[] args) { String name = null; System.out.println(name.length()); }
\2)ArithmeticException mathematical operation exception
public static void main(String[] args) { int num1 = 10; int num2 = 0; int res = num1 / num2; System.out.println("Program continues...."); }
\3) ArrayIndexOutOfBoundsException array index out of bounds exception
public static void main(String[] args) { int[] arr = {1, 2, 3}; for (int i = 0; i <= arr.length; i++) { System.out.println(arr[i]); } }
\4) ClassCastException type conversion exception
public static void main(String[] args) { A b = new B(); //Upward transformation B b2 = (B) b;//Transition down, here is OK C c2 = (C) b;//ClassCastException is thrown here }
class A { } class B extends A { } class C extends A { }
\5) NumberFormatException number format incorrect exception
public static void main(String[] args) { String name = "Xiao Wang learns programming"; //Convert String to int int num = Integer.parseInt(name);//Throw NumberFormatException System.out.println(num);//1234 }
Compilation exception
FileNotFoundException
public static void main(String[] args) { try { FileInputStream fis; fis = new FileInputStream("d:\\aa.jpg"); int len; while ((len = fis.read()) != -1) { System.out.println(len); } fis.close(); } catch (IOException e) { e.printStackTrace(); } }
try-catch-finally
public static void main(String[] args) { //ctrl + atl + t //1. if an exception occurs, the code after the exception will not be executed and will directly enter the catch block //2. if the exception does not occur, the code blocks of try will be executed in sequence, and the catch will not be entered //3. if you want to execute a piece of code (such as closing a connection, releasing resources, etc.) regardless of whether an exception occurs, use the following code - finally try { String str = "Xiao Wang"; int a = Integer.parseInt(str); System.out.println("Number:" + a); } catch (NumberFormatException e) { System.out.println("Abnormal information=" + e.getMessage()); } finally { System.out.println("finally Code block executed..."); } System.out.println("Program continues..."); }
Try catch finally execution sequence summary
Integer class: unpacking and boxing
Transformation and principle of packaging class and basic data
public static void main(String[] args) { //Demonstrate boxing and unpacking of int < --> integer //Before jdk5, manual packing and unpacking //Manual boxing int->integer int n1 = 100; Integer integer = new Integer(n1); Integer integer1 = Integer.valueOf(n1); //Manual unpacking // Integer -> int int i = integer.intValue(); //After jdk5, it can automatically pack and unpack int n2 = 200; // Auto boxing int->integer Integer integer2 = n2; // The underlying layer uses integer valueOf(n2) // Automatic unpacking integer->int int n3 = integer2; // The underlying layer still uses the intValue() method }
Interview questions
Conversion between wrapper type and String type
public static void main(String[] args) { //Wrapper class (integer) ->string Integer i = 100; //Automatic packing //Mode 1 String str1 = i + ""; //Mode 2 String str2 = i.toString(); //Mode 3 String str3 = String.valueOf(i); //String - > wrapper class (Integer) String str4 = "12345"; Integer i2 = Integer.parseInt(str4); //Use to auto box Integer i3 = new Integer(str4); //constructor System.out.println("ok~~"); }
Integer interview questions
public static void main(String[] args) { Integer i = new Integer(1); Integer j = new Integer(1); System.out.println(i == j); //False //Therefore, the range -128 ~ 127 is the direct return /* //1. If i is in integercache low(-128)~IntegerCache. High (127), which is returned directly from the array //2. If it is not in -128~127, directly new Integer(i) public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } */ Integer m = 1; //Underlying integer valueOf(1); -> Read the source code Integer n = 1;//Underlying integer valueOf(1); System.out.println(m == n); //T //Therefore, the range -128 ~ 127 is the direct return //, otherwise, new Integer(xx); Integer x = 128;//Underlying integer valueOf(1); Integer y = 128;//Underlying integer valueOf(1); System.out.println(x == y);//False }
public static void main(String[] args) { //Example 1 Integer i1 = new Integer(127); Integer i2 = new Integer(127); System.out.println(i1 == i2);//F //Example 2 Integer i3 = new Integer(128); Integer i4 = new Integer(128); System.out.println(i3 == i4);//F //Example 3 Integer i5 = 127;//Underlying integer valueOf(127) Integer i6 = 127;//-128~127 System.out.println(i5 == i6); //T //Example 4 Integer i7 = 128; Integer i8 = 128; System.out.println(i7 == i8);//F //Example 5 Integer i9 = 127; //Integer.valueOf(127) Integer i10 = new Integer(127); System.out.println(i9 == i10);//F //Example 6 Integer i11=127; int i12=127; //Only basic data types are available, and the judgment is //Whether the values are the same System.out.println(i11==i12); //T //Example 7 Integer i13=128; int i14=128; System.out.println(i13==i14);//T }
String class
Understanding and creating objects of String class
public static void main(String[] args) { //1.String object is used to save strings, that is, a set of character sequences //2."jack" string constant, character sequence enclosed in double quotation marks //3. the characters of the string are encoded by Unicode characters. One character (regardless of whether it is alphabetic or Chinese) occupies two bytes //4. The string class has many constructors. Overloads of constructors //Commonly used are String s1 = new String(); //String s2 = new String(String original); //String s3 = new String(char[] a); //String s4 = new String(char[] a,int startIndex,int count) //String s5 = new String(byte[] b) //5. the String class implements the interface Serializable [String can be serialized: it can be transmitted over the network] //Interface Comparable [String object can compare sizes] //6. String is a final class and cannot be inherited by other classes //7. String has the attribute private final char value[]; Used to store string contents //8. it must be noted that: value is a final type and cannot be modified (requires skill): that is, value cannot point to //New address, but the content of a single character can be changed String name = "jack"; name = "tom"; System.out.println(name); final char[] value = {'a','b','c'}; char[] v2 = {'t','o','m'}; value[0] = 'H'; //value = v2; Value address cannot be modified }
Two ways to create String objects
Differences between two methods of creating String objects
Interview questions
Common methods of String class
public static void main(String[] args) { //1. equals has been mentioned earlier Compare whether the contents are the same, case sensitive String str1 = "hello"; String str2 = "Hello"; System.out.println(str1.equals(str2));//F // 2.equalsIgnoreCase ignores case to determine whether the contents are equal String username = "johN"; if ("john".equalsIgnoreCase(username)) { System.out.println("Success!"); } else { System.out.println("Failure!"); } // 3.length get the number of characters and the length of the string System.out.println("Xiao Wang".length()); // 4.indexOf gets the index of the first occurrence of a character in a string object. The index starts from 0. If it is not found, it returns -1 String s1 = "wer@terwe@g"; int index = s1.indexOf('@'); System.out.println(index);// 3 System.out.println("weIndex=" + s1.indexOf("we"));//0 // 5.lastIndexOf gets the index of the last occurrence of the character in the string. The index starts from 0. If it is not found, it returns -1 s1 = "wer@terwe@g@"; index = s1.lastIndexOf('@'); System.out.println(index);//11 System.out.println("ter Location of=" + s1.lastIndexOf("ter"));//4 // 6.substring intercepts the substring of the specified range String name = "hello,Zhang San"; //Name Substring (6) intercepts all the following contents from index 6 System.out.println(name.substring(6));//Intercept the following characters //name.substring(0,5) means to intercept from index 0 to index 5-1=4 System.out.println(name.substring(2,5));//llo }
public static void main(String[] args) { // 1.toUpperCase convert to uppercase String s = "heLLo"; System.out.println(s.toUpperCase());//HELLO // 2.toLowerCase System.out.println(s.toLowerCase());//hello // 3.concat concatenation string String s1 = "Precious jade"; s1 = s1.concat("Lindaiyu").concat("Xuebaochai").concat("together"); System.out.println(s1);//Baoyu Lindaiyu xuebaochai together // 4.replace replace characters in string s1 = "Precious jade and Lindaiyu Lindaiyu Lindaiyu"; //In s1, replace all Lindaiyu with xuebaochai // Lao Han's interpretation: s1 After the replace () method is executed, the returned result is the replaced result// Note that there is no effect on S1 String s11 = s1.replace("Precious jade", "jack"); System.out.println(s1);//Baoyu and Lindaiyu Lindaiyu System.out.println(s11);//jack and Lindaiyu // 5.split split split string. For some split characters, we need to escape, such as | \ \ String poem = "Hoe standing grain gradually pawning a midday,Sweat drops under the grass,Who knows Chinese food,Every single grain is the fruit of hard work."; // 1. split the POE based on, and return an array // 2. when splitting a string, if there are special characters, you need to add an escape character\ String[] split = poem.split(","); poem = "E:\\aaa\\bbb"; split = poem.split("\\\\"); System.out.println("==Split content==="); for (int i = 0; i < split.length; i++) { System.out.println(split[i]); } // 6.toCharArray to character array s = "happy"; char[] chs = s.toCharArray(); for (int i = 0; i < chs.length; i++) { System.out.println(chs[i]); } // 7.compareTo compare the size of two strings. If the former is large, // Returns a positive number. If the latter is large, it returns a negative number. If it is equal, it returns 0 // (1) If the length is the same and each character is the same, 0 is returned // (2) If the length is the same or different, but the comparison can be case sensitive // Return if (C1! = C2){ // return c1 - c2; // } // (3) If the previous sections are the same, str1 len - str2. len String a = "jcck";// len = 3 String b = "jack";// len = 4 System.out.println(a.compareTo(b)); // The return value is the value of'c'-'a' = 2 // 8.format format string /* Placeholders are: * %s String%c character%d integer% 2f floating point */ String name = "john"; int age = 10; double score = 56.857; char gender = 'male'; //Concatenate all the information into a string String info = "My name is" + name + "Age is" + age + ",The result is" + score + "Gender is" + gender + ". Hope you like me!"; System.out.println(info); //1. %s , %d , %. 2F%c is called a placeholder //2. these placeholders are replaced by the following variables //3.%s means that it is replaced by a string //4.%d is an integer to replace //5. %.2f means to use decimals for replacement. After replacement, only two decimal places will be retained and rounded //6.%c use char type to replace String formatStr = "My name is%s Age is%d,The result is%.2f Gender is%c.Hope you like me!"; String info2 = String.format(formatStr, name, age, score, gender); System.out.println("info2=" + info2); }
StringBuffer and StringBuilder
StringBuffer class Basic introduction
public static void main(String[] args) { //1. the direct parent class of StringBuffer is AbstractStringBuilder //2. StringBuffer implements Serializable, that is, StringBuffer objects can be serialized //3. AbstractStringBuilder in the parent class has the attribute char[] value, not final // The value array stores the string contents and exports the //4. StringBuffer is a final class and cannot be inherited //5. because the StringBuffer character content has char[] value, all are changing (add / delete) // It is not necessary to change the address every time (that is, it is not necessary to create a new object every time), so the efficiency is higher than that of String StringBuffer stringBuffer = new StringBuffer("hello"); }
String VS StringBuffer
Conversion between String and StringBuffer
public static void main(String[] args) { //See String -->stringbuffer String str = "hello tom"; //Mode 1 using constructors //Note: the returned StringBuffer object has no effect on str itself StringBuffer stringBuffer = new StringBuffer(str); //Method 2 uses the append method StringBuffer stringBuffer1 = new StringBuffer(); stringBuffer1 = stringBuffer1.append(str); //Look at StringBuffer ->string StringBuffer stringBuffer3 = new StringBuffer("Xiao Wang learns programming"); //Method 1: use the toString method provided by StringBuffer String s = stringBuffer3.toString(); //Method 2: use the constructor to handle String s1 = new String(stringBuffer3); }
Common methods of StringBuffer class
public static void main(String[] args) { StringBuffer s = new StringBuffer("hello"); //increase s.append(',');// "hello," s.append("Zhangsanfeng");//"hello, zhangsanfeng" s.append("Zhaomin").append(100).append(true).append(10.5);//"hello, zhangsanfeng, Zhaomin 100true10.5" system out. println(s);// "hello, zhangsanfeng, Zhaomin 100true10.5" //Delete /* * Delete characters at index > =start & & <end * Interpretation: delete characters 11~14 [11, 14) */ s.delete(11, 14); System.out.println(s);//"hello, zhangsanfeng, Zhaomin true10.5" //change //Interpretation, use zhouzhiruo to replace the characters of index 9-11 [9,11) s.replace(9, 11, "Zhouzhiruo"); System.out.println(s);//"hello, zhangsanfeng, zhouzhiruo true10.5" //Finds the index of the specified substring at the first occurrence of the string. If it is not found, it returns -1 int indexOf = s.indexOf("Zhangsanfeng"); System.out.println(indexOf);//6 //insert //Lao Han interpreted that "Zhaomin" was inserted at the position with index 9, and the content with index 9 was automatically moved back s.insert(9, "Zhaomin"); System.out.println(s);//"hello, zhangsanfeng, Zhaomin, zhouzhiruo true10.5" //length System.out.println(s.length());//22 System.out.println(s); }
StringBuffer class classroom test questions
public static void main(String[] args) { String str = null;// ok StringBuffer sb = new StringBuffer(); //ok sb.append(str);//You need to look at the source code. The bottom layer calls the appendNull of AbstractStringBuilder System.out.println(sb.length());//4 System.out.println(sb);//null //The following constructor will throw a NullpointerException StringBuffer sb1 = new StringBuffer(str);//Look at the underlying source code super(str.length() + 16); System.out.println(sb1); }
StringBuffer class classroom test question 2
public static void main(String[] args) { /* Enter the product name and price, and ask to print an example of the effect, using the method learned above: Commodity name commodity price mobile phone 123564.59 / / for example, the price is 3456789.88 Requirements: every three digits in front of the decimal point of the price shall be separated by commas in the output. Train of thought analysis 1. Define a Scanner object to receive the price entered by the user (String) 2. If you want to use the insert of StringBuffer, you need to convert the String to StringBuffer 3. Then use related methods to process strings code implementation */ //new Scanner(System.in) String price = "8123564.59"; StringBuffer sb = new StringBuffer(price); //First complete the simplest implementation 123564.59 //Find the index of the decimal point, and then insert it in the first 3 digits of the position // int i = sb.lastIndexOf("."); // sb = sb.insert(i - 3, ","); //The above two steps need to be processed in a cycle, which is correct for (int i = sb.lastIndexOf(".") - 3; i > 0; i -= 3) { sb = sb.insert(i, ","); } System.out.println(sb);//8,123,564.59 }
StringBuilder class Basic introduction
public static void main(String[] args) { //1. the direct parent class of StringBuffer is AbstractStringBuilder //2. StringBuffer implements Serializable, that is, StringBuffer objects can be serialized //3. AbstractStringBuilder in the parent class has the attribute char[] value, not final // The value array stores the string contents and exports the //4. StringBuffer is a final class and cannot be inherited //5. because the StringBuffer character content has char[] value, all are changing (add / delete) // It is not necessary to change the address every time (that is, it is not necessary to create a new object every time), so the efficiency is higher than that of String StringBuffer stringBuffer = new StringBuffer("hello"); }
StringBuilder common methods
public static void main(String[] args) { //1. StringBuilder inherits AbstractStringBuilder class //2. Serializable is implemented, which indicates that the StringBuilder object can be serialized (the object can be transmitted over the network and saved to a file) //3. StringBuilder is a final class and cannot be inherited //4. the StringBuilder object character sequence is still stored in the char[] value of its parent class AbstractStringBuilder; // Therefore, the character sequence is in the heap //5. the StringBuilder method is not mutually exclusive, that is, there is no synchronized keyword, so it is used in the case of a single thread // StringBuilder StringBuilder stringBuilder = new StringBuilder(); }
Comparison of String, StringBuffer and StringBuilder
StringVsStringBufferVsStringBuilder.java efficiency: StringBuilder > StringBuffer > string
public static void main(String[] args) { long startTime = 0L; long endTime = 0L; StringBuffer buffer = new StringBuffer(""); startTime = System.currentTimeMillis(); for (int i = 0; i < 80000; i++) {//StringBuffer splicing 20000 times buffer.append(String.valueOf(i)); } endTime = System.currentTimeMillis(); System.out.println("StringBuffer Execution time of:" + (endTime - startTime)); StringBuilder builder = new StringBuilder(""); startTime = System.currentTimeMillis(); for (int i = 0; i < 80000; i++) {//StringBuilder splicing 20000 times builder.append(String.valueOf(i)); } endTime = System.currentTimeMillis(); System.out.println("StringBuilder Execution time of:" + (endTime - startTime)); String text = ""; startTime = System.currentTimeMillis(); for (int i = 0; i < 80000; i++) {//String splicing 20000 text = text + i; } endTime = System.currentTimeMillis(); System.out.println("String Execution time of:" + (endTime - startTime)); }
Selection of String, StringBuffer and StringBuilder
List | ArrayList | Vector
List interface and common methods
Basic introduction to List interface
@SuppressWarnings({"all"}) public static void main(String[] args) { //1. the elements in the list set class are orderly (i.e. the adding order is the same as the extracting order) and repeatable [case] List list = new ArrayList(); list.add("jack"); list.add("tom"); list.add("mary"); list.add("hsp"); list.add("tom"); System.out.println("list=" + list); //2. each element in the list set has its corresponding sequential index, that is, it supports indexes // Index starts at 0 System.out.println(list.get(3));//hsp }
Common methods of List interface
@SuppressWarnings({"all"}) public static void main(String[] args) { List list = new ArrayList(); list.add("Zhangsanfeng"); list.add("Jia Baoyu"); // void add(int index, Object ele): inserts an ele element at the index position //Insert an object at index = 1 list.add(1, "oracle "); System.out.println("list=" + list); // boolean addAll(int index, Collection eles): add all elements in eles from the index position List list2 = new ArrayList(); list2.add("jack"); list2.add("tom"); list.addAll(1, list2); System.out.println("list=" + list); // Object get(int index): get the element at the specified index position //Yes // int indexOf(Object obj): returns the position where obj first appears in the collection System.out.println(list.indexOf("tom"));//2 // int lastIndexOf(Object obj): returns the last occurrence of obj in the current set list.add("oracle "); System.out.println("list=" + list); System.out.println(list.lastIndexOf("oracle ")); // Object remove(int index): removes the element at the specified index position and returns this element list.remove(0); System.out.println("list=" + list); // Object set(int index, Object ele): sets the element at the specified index position to ele, which is equivalent to replacement list.set(1, "Mary"); System.out.println("list=" + list); // List subList(int fromIndex, int toIndex): returns a subset from fromIndex to toIndex // Note the returned subset fromindex < = sublist < toindex List returnlist = list.subList(0, 2); System.out.println("returnlist=" + returnlist); }
List interface class exercise
@SuppressWarnings({"all"}) public static void main(String[] args) { /* Add more than 10 elements (such as String "hello"), and insert an element "hanshunping education" in position 2, Get the fifth element, delete the sixth element, modify the seventh element, and traverse the collection using an iterator, Requirements: use the implementation class ArrayList of List to complete. */ List list = new ArrayList(); for (int i = 0; i < 12; i++) { list.add("hello" + i); } System.out.println("list=" + list); //Insert an element "hanshunping education" in position 2 list.add(1, "Hanshunping Education"); System.out.println("list=" + list); //Get the 5th element System.out.println("Fifth element=" + list.get(4)); //Delete the 6th element list.remove(5); System.out.println("list=" + list); //Modify the 7th element list.set(6, "Romance of the Three Kingdoms"); System.out.println("list=" + list); //Traversing collections using iterators Iterator iterator = list.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println("obj=" + obj); } }
Three traversal methods of List [ArrayList, LinkedList,Vector]
@SuppressWarnings({"all"}) public static void main(String[] args) { //Implementation subclass of the List interface Vector LinkedList //List list = new ArrayList(); //List list = new Vector(); List list = new LinkedList(); list.add("jack"); list.add("tom"); list.add("Yu-Shiang Shredded Pork"); list.add("Beijing roast duck"); //ergodic //1. iterator Iterator iterator = list.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println(obj); } System.out.println("=====enhance for====="); //2. enhanced for for (Object o : list) { System.out.println("o=" + o); } System.out.println("=====ordinary for===="); //3. use common for for (int i = 0; i < list.size(); i++) { System.out.println("object=" + list.get(i)); } }
Class exercise 2 of implementation class
public static void main(String[] args) { //List list = new ArrayList(); List list = new LinkedList(); //List list = new Vector(); list.add(new Book("The Dream of Red Mansion", "Cao Xueqin", 100)); list.add(new Book("Journey to the West", "WuChengEn", 10)); list.add(new Book("Water Margin", "Shi Naian", 19)); list.add(new Book("three countries", "Luo Guanzhong", 80)); //list.add(new Book("journey to the west", "WuChengEn", 10)); //How to sort collections //ergodic for (Object o : list) { System.out.println(o); } //Bubble sort sort(list); System.out.println("==After sorting=="); for (Object o : list) { System.out.println(o); } } //Static method //The price requirement is from small to large public static void sort(List list) { int listSize = list.size(); for (int i = 0; i < listSize - 1; i++) { for (int j = 0; j < listSize - 1 - i; j++) { //Take out the object Book Book book1 = (Book) list.get(j); Book book2 = (Book) list.get(j + 1); if (book1.getPrice() > book2.getPrice()) {//exchange list.set(j, book2); list.set(j + 1, book1); } } } }
ArrayList underlying structure and source code analysis
Precautions for ArrayList
Source code analysis of the underlying operating mechanism of ArrayList (key and difficult points)
public static void main(String[] args) { //Lao Han interprets the source code //Note, note, note, by default, the data displayed in Debug is simplified. If you want to see the complete data //Settings are required// Creating an ArrayList object with a parameterless constructor //ArrayList list = new ArrayList(); ArrayList list = new ArrayList(8); //Use for to add 1-10 data to the list set for (int i = 1; i <= 10; i++) { list.add(i); } //Use for to add 11-15 data to the list set for (int i = 11; i <= 15; i++) { list.add(i); } list.add(100); list.add(200); list.add(null); }
[external link image transfer failed. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-t6lytt3x-1640865302556)( https://gitee.com/wanghanhao/haostudent/raw/master/image-20211230194455685.png )]
Vector underlying structure and source code analysis
Basic introduction to Vector
public static void main(String[] args) { //Parameterless constructor //Construction with parameters Vector vector = new Vector(8); for (int i = 0; i < 10; i++) { vector.add(i); } vector.add(100); System.out.println("vector=" + vector); //Lao Han interprets the source code //1. new Vector() bottom layer /* public Vector() { this(10); } Supplement: if Vector vector = new Vector(8); How to walk: public Vector(int initialCapacity) { this(initialCapacity, 0); } 2. vector.add(i) 2.1 //The following method adds data to the vector set public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; } 2.2 //Determine whether the capacity expansion condition is required: mincapacity - elementdata length>0 private void ensureCapacityHelper(int minCapacity) { // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } 2.3 //If the required array size is not enough, it will be expanded. Expansion algorithm //newCapacity = oldCapacity + ((capacityIncrement > 0) ? // capacityIncrement : oldCapacity); //That is to double the capacity private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); } */ }
Comparison of Vector and ArrayList
LinkedList underlying structure
Comprehensive description of LinkedList
Underlying operation mechanism of LinkedList
public static void main(String[] args) { //Simulate a simple two-way linked list Node jack = new Node("jack"); Node tom = new Node("tom"); Node hsp = new Node("Lao Han"); //Connect three nodes to form a two-way linked list //jack -> tom -> hsp jack.next = tom; tom.next = hsp; //hsp -> tom -> jack hsp.pre = tom; tom.pre = jack; Node first = jack;//Let the first reference point to jack, which is the head node of the bidirectional linked list Node last = hsp; //Let the last reference point to the hsp, which is the tail node of the bidirectional linked list //Demonstration, traversal from beginning to end System.out.println("===Traversal from beginning to end==="); while (true) { if (first == null) { break; } //Output first information System.out.println(first); first = first.next; } //Demo, traversal from end to end System.out.println("====Traversal from end to end===="); while (true) { if (last == null) { break; } //Output last information System.out.println(last); last = last.pre; } //Demonstrate how convenient it is to add objects / data to the linked list //The requirement is to insert an object smith directly in tom --------- Lao Han //1. create a Node node first. The name is smith Node smith = new Node("smith"); //Now let's add smith to the two-way linked list smith.next = hsp; smith.pre = tom; hsp.pre = smith; tom.next = smith; //Let first point to jack again first = jack;//Let the first reference point to jack, which is the head node of the bidirectional linked list System.out.println("===Traversal from beginning to end==="); while (true) { if (first == null) { break; } //Output first information System.out.println(first); first = first.next; } last = hsp; //Let last point to the last node again //Demo, traversal from end to end System.out.println("====Traversal from end to end===="); while (true) { if (last == null) { break; } //Output last information System.out.println(last); last = last.pre; } }
//Define a Node class, and the Node object represents a Node of the bidirectional linked list class Node { public Object item; //Real data storage public Node next; //Point to the next node public Node pre; //Point to previous node public Node(Object name) { this.item = name; } public String toString() { return "Node name=" + item; } }
Cases of adding, deleting and modifying LinkedList
public static void main(String[] args) { LinkedList linkedList = new LinkedList(); linkedList.add(1); linkedList.add(2); linkedList.add(3); System.out.println("linkedList=" + linkedList); //Demonstrate a method for deleting nodes linkedList.remove(); // The first node is deleted by default //linkedList.remove(2); System.out.println("linkedList=" + linkedList); //Modify a node object linkedList.set(1, 999); System.out.println("linkedList=" + linkedList); //Get a node object //get(1) is the second object to get the bidirectional linked list Object o = linkedList.get(1); System.out.println(o);//999 //Because LinkedList implements the List interface, the traversal mode is System.out.println("===LinkeList Traversal iterator===="); Iterator iterator = linkedList.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println("next=" + next); } System.out.println("===LinkeList Traversal enhancement for===="); for (Object o1 : linkedList) { System.out.println("o1=" + o1); } System.out.println("===LinkeList Traversal normal for===="); for (int i = 0; i < linkedList.size(); i++) { System.out.println(linkedList.get(i)); } //Old Korean source code reading /* 1. LinkedList linkedList = new LinkedList(); public LinkedList() {} 2. At this time, the linklist property first = null last = null 3. Perform add public boolean add(E e) { linkLast(e); return true; } 4.Add the new node to the end of the bidirectional linked list void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; } */ /* Lao Han reads the source code linkedlist remove(); // The first node is deleted by default 1. Execute removeFirst public E remove() { return removeFirst(); } 2. implement public E removeFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); } 3. Execute unlinkFirst to remove the first node of the bidirectional linked list pointed to by f private E unlinkFirst(Node<E> f) { // assert f == first && f != null; final E element = f.item; final Node<E> next = f.next; f.item = null; f.next = null; // help GC first = next; if (next == null) last = null; else next.prev = null; size--; modCount++; return element; } */ }
ArrayList and LinkedList comparison
HashSet and LinkedHashSet
Set interface and common methods
Basic introduction to Set interface
Common methods of Set interface
Like the List interface, the Set interface is also a sub interface of the Collection. Therefore, common methods are the same as the Collection interface
Traversal mode of Set interface
Examples of common methods of Set interface
public static void main(String[] args) { //Lao Han's interpretation //1. explain the methods of the Set interface with the implementation class HashSet of the Set interface //2. the object of the implementation class of the Set interface (Set interface object) cannot store duplicate elements. You can add a null //3. the data stored in the set interface object is out of order (that is, the order of adding is inconsistent with the order of fetching) //4. note: Although the order of taking out is not the order of adding, it is fixed Set set = new HashSet(); set.add("john"); set.add("lucy"); set.add("john");//repeat set.add("jack"); set.add("hsp"); set.add("mary"); set.add(null);// set.add(null);//Add null again for (int i = 0; i < 10; i++) { System.out.println("set=" + set); } //ergodic //Method 1: using iterators System.out.println("=====Using Iterators ===="); Iterator iterator = set.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println("obj=" + obj); } set.remove(null); //Method 2: enhanced for System.out.println("=====enhance for===="); for (Object o : set) { System.out.println("o=" + o); } //The set interface object cannot be obtained by index }
Set interface implementation class -HashSet
Comprehensive description of HashSet
public static void main(String[] args) { //Lao Han's interpretation //1. source code of constructor /* public HashSet() { map = new HashMap<>(); } 2. HashSet Null can be stored, but there can only be one null, that is, the element cannot be repeated */ Set hashSet = new HashSet(); hashSet.add(null); hashSet.add(null); System.out.println("hashSet=" + hashSet); }
HashSet case description
public static void main(String[] args) { HashSet set = new HashSet(); //explain //1. after the add method is executed, a boolean value will be returned //2. if the addition succeeds, return true; otherwise, return false //3. you can specify which object to delete through remove System.out.println(set.add("john"));//T System.out.println(set.add("lucy"));//T System.out.println(set.add("john"));//F System.out.println(set.add("jack"));//T System.out.println(set.add("Rose"));//T set.remove("john"); System.out.println("set=" + set);//3 set = new HashSet(); System.out.println("set=" + set);//0 //4 can't HashSet add the same element / data? set.add("lucy");//Successfully added set.add("lucy");//Can't join set.add(new Dog("tom"));//OK set.add(new Dog("tom"));//Ok System.out.println("set=" + set); //It's deepening A very classic interview question //Look at the source code and analyze it. First, leave a hole for the little partner. After talking about the source code, you will know //Go to his source code, that is, what happened to add? = > Underlying mechanism set.add(new String("hsp"));//ok set.add(new String("hsp"));//Can't join System.out.println("set=" + set); }
class Dog { //Dog class defined private String name; public Dog(String name) { this.name = name; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + '}'; } }
HashSet underlying mechanism description
public static void main(String[] args) { HashSet hashSet = new HashSet(); hashSet.add("java");//At this position, the first add analysis is completed hashSet.add("php");// At this position, the second add analysis is completed hashSet.add("java"); System.out.println("set=" + hashSet); /* Lao Han's interpretation of the source code of HashSet 1. Execute HashSet() public HashSet() { map = new HashMap<>(); } 2. Execute add() public boolean add(E e) {//e = "java" return map.put(e, PRESENT)==null;//(static) PRESENT = new Object(); } 3.Execute put(), which will execute hash(key) to get the hash value corresponding to the key algorithm H = key hashCode()) ^ (h >>> 16) public V put(K key, V value) {//key = "java" value = PRESENT share return putVal(hash(key), key, value, false, true); } 4.Execute putVal final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; //Auxiliary variables defined //table It is an array of HashMap. The type is Node[] //if Statement indicates that if the current table is null or the size =0 //It is the first expansion to 16 spaces if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; //(1)According to the key, get the hash to calculate the index location of the key in the table //And assign the object at this position to p //(2)Determine whether p is null //(2.1) If p is null, it means that the element has not been stored yet. Create a Node (key="java",value=PRESENT) //(2.2) Put it at this positiontab[i] = newnode (hash, key, value, null) if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { //A development tip: when local variables (auxiliary variables) are required, create Node<K,V> e; K k; // //If the first element of the linked list corresponding to the current index position is the same as the hash value of the key to be added //And one of the following two conditions is met: //(1) The key to be added and the key of the Node pointed to by p are the same object //(2) p The equals() of the key of the Node pointed to is the same as the key to be added after comparison //Can't join if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k)))) e = p; //Then judge whether p is a red black tree. / / if it is a red black tree, call putTreeVal to add it else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else {//If the table corresponds to the index position and is already a linked list, use the for loop comparison //(1) If it is different from each element of the linked list in turn, it will be added to the end of the linked list // Note that after adding elements to the linked list, you can immediately judge whether the linked list has reached 8 nodes // , Call treeifyBin() to tree the current linked list (turn it into a red black tree) // Note that when converting to red black tree, judge the conditions // if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY(64)) // resize(); // If the above conditions are true, first expand the table// Only when the above conditions are not tenable, can it be converted to red black tree //(2) In the process of comparing with each element of the linked list in turn, if there is the same situation, break directly for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD(8) - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; //size That is, every time we add a Node(k,v,h,next), size++ if (++size > threshold) resize();//Capacity expansion afterNodeInsertion(evict); return null; } */ }
public static void main(String[] args) { /* HashSet The bottom layer is HashMap. When it is added for the first time, the table array is expanded to 16, The threshold is 16* the LoadFactor is 0.75 = 12 If the table array uses the critical value of 12, it will be expanded to 16 * 2 = 32, The new critical value is 32*0.75 = 24, and so on */ HashSet hashSet = new HashSet(); // for(int i = 1; i <= 100; i++) { // hashSet.add(i);//1,2,3,4,5...100 // } /* In Java8, if the number of elements in a linked list reaches tree_ Threshold (default is 8), And the size of the table > = min_ TREEIFY_ Capability (64 by default) will be treelized (red black tree), otherwise the array capacity expansion mechanism will still be used */ // for(int i = 1; i <= 12; i++) { // hashSet.add(new A(i));// // } /* When we add an element to the hashset, -> node - > table, we add a size++ */ for (int i = 1; i <= 7; i++) {//Seven A objects are added to A linked list of table hashSet.add(new A(i));// } for (int i = 1; i <= 7; i++) {//Seven B objects are added to another linked list of the table hashSet.add(new B(i));// } }
class B { private int n; public B(int n) { this.n = n; } @Override public int hashCode() { return 200; } } class A { private int n; public A(int n) { this.n = n; } @Override public int hashCode() { return 100; } }
HashSet class exercise 1
public static void main(String[] args) { /** Define an Employee class, which contains: private member attribute name,age requirements: Create three Employee objects and put them into the HashSet When the values of name and age are the same, they are considered to be the same employees and cannot be added to the HashSet set set */ HashSet hashSet = new HashSet(); hashSet.add(new Employee("milan", 18));//ok hashSet.add(new Employee("smith", 28));//ok hashSet.add(new Employee("milan", 18));//Failed to join// Answer, how many are added? 3 System.out.println("hashSet=" + hashSet); }
//Create Employee class Employee { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", age=" + age + '}'; } public void setAge(int age) { this.age = age; } //If the name and age values are the same, the same hash value is returned @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Employee employee = (Employee) o; return age == employee.age && Objects.equals(name, employee.name); } @Override public int hashCode() { return Objects.hash(name, age); } }
HashSet after class exercise 2
Set interface implementation class LinkedHashSet
Comprehensive description of LinkedHashSet
LinkedHashSet after class exercises
public static void main(String[] args) { LinkedHashSet linkedHashSet = new LinkedHashSet(); linkedHashSet.add(new Car("Alto", 1000));//OK linkedHashSet.add(new Car("audi", 300000));//OK linkedHashSet.add(new Car("Ferrari", 10000000));//OK linkedHashSet.add(new Car("audi", 300000));//Can't join linkedHashSet.add(new Car("Porsche", 70000000));//OK linkedHashSet.add(new Car("audi", 300000));//Can't join System.out.println("linkedHashSet=" + linkedHashSet); }
/** * Car Class (attribute: name,price). If name and price are the same, * It is considered to be the same element and cannot be added. 5min */ class Car { private String name; private double price; public Car(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "\nCar{" + "name='" + name + '\'' + ", price=" + price + '}'; } //Override equals method and hashCode //When the name and price are the same, the same hashCode value is returned, and equals returns t @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Car car = (Car) o; return Double.compare(car.price, price) == 0 && Objects.equals(name, car.name); } @Override public int hashCode() { return Objects.hash(name, price); } }
HashMap and HashTable (super focus)
Map interface and common methods
Features of Map interface implementation class [very practical]
public static void main(String[] args) { //Lao Han interprets the characteristics of the Map interface implementation class and uses the implementation class HashMap //1. Map and Collection exist side by side. Used to save data with mapping relationship: key value (double column element) //2. the key and value in the map can be data of any reference type and will be encapsulated in the HashMap$Node object //3. duplicate key s in the map are not allowed. The reason is the same as that of the HashSet. The source code has been analyzed previously// 4. the value in the map can be repeated //5. the key and value of the map can be null. Note that the key is null // There can only be one, value is null, and there can be multiple //6. commonly used String class as key of Map //7. there is a one-way one-to-one relationship between key and value, that is, the corresponding value can always be found through the specified key Map map = new HashMap(); map.put("no1", "oracle ");//k-v map.put("no2", "zhang wuji");//k-v map.put("no1", "Zhangsanfeng");//When there is the same K, it is equivalent to substitution map.put("no3", "zhangsanfeng")// k-v map.put(null, null); //k-v map.put(null, "abc"); //Equivalent substitution map.put("no4", null); //k-v map.put("no5", null); //k-v map.put(1, "Zhaomin");//k-v map.put(new Object(), "Golden King ");//k-v // Pass in the key through the get method, and the corresponding value will be returned System.out.println(map.get("no2"));//zhang wuji System.out.println("map=" + map); }
Common methods of Map interface
public static void main(String[] args) { //Demonstrate common methods of map interface Map map = new HashMap(); map.put("Deng Chao", new Book("", 100));//OK map.put("Deng Chao", "Sun Li");//Replace - > analyze the source code later map.put("Wangbaoqiang", "MaRong");//OK map.put("Song Zhe", "MaRong");//OK map.put("Liulingbo", null);//OK map.put(null, "Liu Yifei");//OK map.put("Lu Han", "Guanxiaotong");//OK map.put("hsp", "hsp My wife"); System.out.println("map=" + map); // remove: delete mapping relationship based on key map.remove(null); System.out.println("map=" + map); // Get: get value based on key Object val = map.get("Lu Han"); System.out.println("val=" + val); // size: get the number of elements System.out.println("k-v=" + map.size()); // isEmpty: judge whether the number is 0 System.out.println(map.isEmpty());//F // Clear: clear k-v //map.clear(); System.out.println("map=" + map); // containsKey: find whether the key exists System.out.println("result=" + map.containsKey("hsp"));//T }
class Book { private String name; private int num; public Book(String name, int num) { this.name = name; this.num = num; } }
Map interface traversal method
public static void main(String[] args) { Map map = new HashMap(); map.put("Deng Chao", "Sun Li"); map.put("Wangbaoqiang", "MaRong"); map.put("Song Zhe", "MaRong"); map.put("Liulingbo", null); map.put(null, "Liu Yifei"); map.put("Lu Han", "Guanxiaotong"); //Group 1: take out all keys first, and take out the corresponding Value through the Key Set keyset = map.keySet(); //(1) Enhanced for System.out.println("-----The first way-------"); for (Object key : keyset) { System.out.println(key + "-" + map.get(key)); } //(2) Iterator System.out.println("----The second way--------"); Iterator iterator = keyset.iterator(); while (iterator.hasNext()) { Object key = iterator.next(); System.out.println(key + "-" + map.get(key)); } //Group 2: take out all values Collection values = map.values(); //Here you can use the traversal method used by all Collections //(1) Enhanced for System.out.println("---Remove all value enhance for----"); for (Object value : values) { System.out.println(value); } //(2) Iterator System.out.println("---Remove all value iterator ----"); Iterator iterator2 = values.iterator(); while (iterator2.hasNext()) { Object value = iterator2.next(); System.out.println(value); } //Group 3: obtain k-v through EntrySet Set entrySet = map.entrySet();// EntrySet<Map.Entry<K,V>> //(1) Enhanced for System.out.println("----use EntrySet of for enhance(Type 3)----"); for (Object entry : entrySet) { //Convert entry to map Entry Map.Entry m = (Map.Entry) entry; System.out.println(m.getKey() + "-" + m.getValue()); } //(2) Iterator System.out.println("----use EntrySet Iterator for(Type 4)----"); Iterator iterator3 = entrySet.iterator(); while (iterator3.hasNext()) { Object entry = iterator3.next(); //System.out.println(next.getClass());//HashMap$Node - Implementation - > map Entry (getKey,getValue) //Transform map Entry Map.Entry m = (Map.Entry) entry; System.out.println(m.getKey() + "-" + m.getValue()); } }
Map interface class exercise
public static void main(String[] args) { //Completion code Map hashMap = new HashMap(); //Add object hashMap.put(1, new Emp("jack", 300000, 1)); hashMap.put(2, new Emp("tom", 21000, 2)); hashMap.put(3, new Emp("milan", 12000, 3)); //Traverse 2 ways //And traverse the employees whose wages are more than 18000 (at least two traversal methods) //1. use keyset - > enhance for Set keySet = hashMap.keySet(); System.out.println("====The first traversal method===="); for (Object key : keySet) { //Get value first Emp emp = (Emp) hashMap.get(key); if (emp.getSal() > 18000) { System.out.println(emp); } } //2. use entryset - > iterator // Reflect difficult knowledge points // Taste slowly. The more you taste, the more you taste Set entrySet = hashMap.entrySet(); System.out.println("======iterator ======"); Iterator iterator = entrySet.iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); //Get key and value through entry Emp emp = (Emp) entry.getValue(); if (emp.getSal() > 18000) { System.out.println(emp); } } }
/** * Add 3 employee objects using HashMap. It is required that * Key: employee id * Value: employee object * <p> * And traverse the employees whose wages are more than 18000 (at least two traversal methods) * Employee category: name, salary, employee id */ class Emp { private String name; private double sal; private int id; public Emp(String name, double sal, int id) { this.name = name; this.sal = sal; this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Emp{" + "name='" + name + '\'' + ", sal=" + sal + ", id=" + id + '}'; } }
Map interface implementation class -HashMap
HashMap summary
HashMap underlying mechanism and source code analysis
HashMap underlying mechanism and source code analysis
public static void main(String[] args) { HashMap map = new HashMap(); map.put("java", 10);//ok map.put("php", 10);//ok map.put("java", 20);//Replace value System.out.println("map=" + map);// /*Lao Han interprets the source code + diagram of HashMap 1. Execute constructor new HashMap() Initialization load factor loadfactor = 0.75 HashMap$Node[] table = null 2. Execute put and call the hash method to calculate the hash value of the key (H = key.hashcode()) ^ (H > > > 16) public V put(K key, V value) {//K = "java" value = 10 return putVal(hash(key), key, value, false, true); } 3. Execute putVal final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i;//Auxiliary variable //If the underlying table array is null or length =0, it will be expanded to 16 if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; //Take the Node at the index position of the table corresponding to the hash value. If it is null, directly add the k-v //, Create a Node and join it if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k;//Auxiliary variable // If the hash of the key at the index position of the table is the same as the hash value of the new key, // (the key of the existing node of the table and the key to be added are the same object | equals returns true) // You think you can't add new k-v if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; else if (p instanceof TreeNode)//If the existing Node of the current table is a red black tree, it will be processed as a red black tree e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { //If the found node is followed by a linked list, it will be compared circularly for (int binCount = 0; ; ++binCount) {//Dead cycle if ((e = p.next) == null) {//If the entire linked list is not the same as him, it will be added to the end of the linked list p.next = newNode(hash, key, value, null); //After adding, judge whether the number of current linked lists has reached 8, and then //Call the treeifyBin method to convert the red black tree if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && //In the process of circular comparison, if the same is found, it will break and just replace value ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; //Replace, key corresponds to value afterNodeAccess(e); return oldValue; } } ++modCount;//Every time a Node is added, the size++ if (++size > threshold[12-24-48])//If size > critical value, expand the capacity resize(); afterNodeInsertion(evict); return null; } 5. About treelization (turning into red black tree) //If the table is null or the size has not reached 64, it will not be trealized for the time being, but will be expanded// Otherwise, it will be really tree like - > pruning final void treeifyBin(Node<K,V>[] tab, int hash) { int n, index; Node<K,V> e; if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY) resize(); } */ }
public static void main(String[] args) { HashMap hashMap = new HashMap(); for (int i = 1; i <= 12; i++) { hashMap.put(i, "hello"); } hashMap.put("aaa", "bbb"); System.out.println("hashMap=" + hashMap);//12 k-v //Assign a task, design your own code to verify, and expand the capacity of the table //0 -> 16(12) -> 32(24) -> 64(64*0.75=48)-> 128 (96) -> //Design their own programs, verify - < enhance their ability to read the source code Look at someone else's code.} } class A { private int num; public A(int num) { this.num = num; } //The hashCode of all A objects is 100 // @Override // public int hashCode() { // return 100; // } @Override public String toString() { return "\nA{" + "num=" + num + '}'; } }
Map interface implementation class -Hashtable
Basic introduction to HashTable
Comparison between Hashtable and HashMap
Summary - how to select collection implementation classes in development (remember)
Multi thread explanation
Thread related concepts
Program
process
What is a thread
Other related concepts
[external link image transfer failed. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (IMG dujscror-1640865302568)( https://gitee.com/wanghanhao/haostudent/raw/master/image-20211230161753393.png )]
Basic thread usage
Two ways to create threads
Thread application case 1- inherit thread class
public static void main(String[] args) throws InterruptedException { //Create Cat objects that can be used as threads Cat cat = new Cat(); //Old Korean reading source code /* (1) public synchronized void start() { start0(); } (2) //start0() It is a local method, a JVM call, and the bottom layer is a c/c++ implementation //The real effect of multithreading is start0(), not run private native void start0(); */ cat.start();//Start the thread - > the run method that will eventually execute cat //cat. run();// The run method is an ordinary method. If a thread is not really started, the run method will be executed completely before downward execution //Note: when the main thread starts a sub thread thread Thread-0, the main thread will not block and will continue to execute //At this time, the main thread and the sub thread execute alternately System.out.println("main thread continues to execute" + thread. Currentthread() getName());// Name main for (int i = 0; i < 60; i++) { System.out.println("Main thread i=" + i); //Hibernate the main thread Thread.sleep(1000); } }
//Lao Han description //1. when a class inherits the Thread class, it can be used as a Thread //2. we will rewrite the run method and write our own business code //3. the run thread class implements the run method of the Runnable interface /* @Override public void run() { if (target != null) { target.run(); } } */ class Cat extends Thread { int times = 0; @Override public void run() {//Rewrite the run method and write your own business logic while (true) { //The thread every 1 second. Output "meow meow, I am a kitten" on the console System.out.println("Meow meow, I'm a kitten" + (++times) + " Thread name=" + Thread.currentThread().getName()); //Let the thread sleep for 1 second ctrl+alt+t try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (times == 80) { break;//When the times reaches 80, exit while, and the thread also exits..} } } } }
Thread application case 2- implementation of Runnable interface
public static void main(String[] args) { Dog dog = new Dog(); //dog.start(); Start cannot be called here //Create a Thread object, put the dog object (Runnable) into the Thread Thread thread = new Thread(dog); thread.start(); // Tiger tiger = new Tiger();// Implemented Runnable // ThreadProxy threadProxy = new ThreadProxy(tiger); // threadProxy.start(); }
class Animal { } class Tiger extends Animal implements Runnable { @Override public void run() { System.out.println("The tiger howled...."); } } //Thread proxy class, simulating a minimalist thread class class ThreadProxy implements Runnable {//You can treat the Proxy class as ThreadProxy private Runnable target = null;//Property of type Runnable @Override public void run() { if (target != null) { target.run();//Dynamic binding (run type Tiger) } } public ThreadProxy(Runnable target) { this.target = target; } public void start() { start0();//This method really implements the multithreaded method } public void start0() { run(); } } class Dog implements Runnable { //Develop threads by implementing the Runnable interface int count = 0; @Override public void run() { //Common method while (true) { System.out.println("Puppy barks..hi" + (++count) + Thread.currentThread().getName()); //Sleep for 1 second try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 10) { break; } } } }
Thread use case - multithreaded execution
public static void main(String[] args) { T1 t1 = new T1(); T2 t2 = new T2(); Thread thread1 = new Thread(t1); Thread thread2 = new Thread(t2); thread1.start();//Start the first thread thread2.start();//Start the second thread //... } }
class T1 implements Runnable { int count = 0; @Override public void run() { while (true) { //Output "hello,world" every 1 second for 10 times System.out.println("hello,world " + (++count)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 60) { break; } } } } class T2 implements Runnable { int count = 0; @Override public void run() { //Output "hi" every 1 second for 5 times while (true) { System.out.println("hi " + (++count)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 50) { break; } } } }
How threads understand
The difference between inheriting thread and implementing Runnable
public static void main(String[] args) { //test // SellTicket01 sellTicket01 = new SellTicket01(); // SellTicket01 sellTicket02 = new SellTicket01(); // SellTicket01 sellTicket03 = new SellTicket01(); // // //We will oversold here// sellTicket01.start();// Start ticket selling thread // sellTicket02.start();// Start ticket selling thread // sellTicket03.start();// Start ticket selling thread System.out.println("===Use the implementation interface to sell tickets====="); SellTicket02 sellTicket02 = new SellTicket02(); new Thread(sellTicket02).start();//1st thread - window new Thread(sellTicket02).start();//2nd thread - window new Thread(sellTicket02).start();//3rd thread - window }
//Using Thread mode class SellTicket01 extends Thread { private static int ticketNum = 100;//Let multiple threads share ticketNum @Override public void run() { while (true) { if (ticketNum <= 0) { System.out.println("End of ticket sales..."); break; } //Sleep 50ms, analog try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket" + " Remaining votes=" + (--ticketNum)); } } } //Implementation interface mode class SellTicket02 implements Runnable { private int ticketNum = 100;//Let multiple threads share ticketNum @Override public void run() { while (true) { if (ticketNum <= 0) { System.out.println("End of ticket sales..."); break; } //Sleep 50ms, analog try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket" + " Remaining votes=" + (--ticketNum));//1 - 0 - -1 - -2 } } }
Thread termination
Basic description
Application cases
Common thread methods
Common methods group 1
Notes and details
Application cases
Common methods group II
Application cases
Test the yield and join methods, pay attention to the characteristics of the methods, and watch the teacher's code demonstration
Classroom exercises
public static void main(String[] args) throws InterruptedException { Thread t3 = new Thread(new T3());//Create child thread for (int i = 1; i <= 10; i++) { System.out.println("hi " + i); if (i == 5) {//Description the main thread outputs hi for 5 times t3.start();//Start child thread output Hello t3.join();// Immediately insert the T3 sub thread into the main thread and let T3 execute first } Thread.sleep(1000);//Output hi once and let the main thread sleep for 1s } }
class T3 implements Runnable { private int count = 0; @Override public void run() { while (true) { System.out.println("hello " + (++count)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 10) { break; } } } }
User threads and daemon threads
Application cases
Let's test how to set a thread as a daemon thread
Thread lifecycle
Thread The state enumeration represents several states of a thread
Thread state transition diagram
Writer view thread status
public static void main(String[] args) throws InterruptedException { T t = new T(); System.out.println(t.getName() + " state " + t.getState()); t.start(); while (Thread.State.TERMINATED != t.getState()) { System.out.println(t.getName() + " state " + t.getState()); Thread.sleep(500); } System.out.println(t.getName() + " state " + t.getState()); }
class T extends Thread { @Override public void run() { while (true) { for (int i = 0; i < 10; i++) { System.out.println("hi " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } break; } } }
Synchronization of threads
Let's start with a question
Synchronized
Thread synchronization mechanism
Synchronization specific method -Synchronized
Analyze the principle of synchronization
mutex
Basic introduction
Use mutex lock to solve ticket selling problem
public static void main(String[] args) { //test // SellTicket01 sellTicket01 = new SellTicket01(); // SellTicket01 sellTicket02 = new SellTicket01(); // SellTicket01 sellTicket03 = new SellTicket01(); // // //We will oversold here// sellTicket01.start();// Start ticket selling thread // sellTicket02.start();// Start ticket selling thread // sellTicket03.start();// Start ticket selling thread // System.out.println("=== use the implementation interface method to sell tickets ===="); // SellTicket02 sellTicket02 = new SellTicket02(); // // new Thread(sellTicket02).start();// 1st thread - window // new Thread(sellTicket02).start();// 2nd thread - window // new Thread(sellTicket02).start();// 3rd thread - window //Test one SellTicket03 sellTicket03 = new SellTicket03(); new Thread(sellTicket03).start();//1st thread - window new Thread(sellTicket03).start();//2nd thread - window new Thread(sellTicket03).start();//3rd thread - window }
//Implement interface mode, and use synchronized to realize thread synchronization class SellTicket03 implements Runnable { private int ticketNum = 100;//Let multiple threads share ticketNum private boolean loop = true;//Control run method variables Object object = new Object(); //The lock of the synchronous method (static) is the current class itself //Lao Han's interpretation //1. the public synchronized static void m1() {} lock is added to sellticket03 class //2. if you implement a synchronized code block in a static method /* synchronized (SellTicket03 .class) { System.out.println("m2"); } */ public synchronized static void m1() { } public static void m2() { synchronized (SellTicket03.class) { System.out.println("m2"); } } //Lao Han description //1. public synchronized void sell() {} is a synchronization method //2. the lock is on this object //3. you can also write synchronize on the code block to synchronize the code block. The mutex is still on this object public /*synchronized*/ void sell() { //Synchronous method. At the same time, only one thread can execute the sell method synchronized (/*this*/ object) { if (ticketNum <= 0) { System.out.println("End of ticket sales..."); loop = false; return; } //Sleep 50ms, analog try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket" + " Remaining votes=" + (--ticketNum));//1 - 0 - -1 - -2 } } @Override public void run() { while (loop) { sell();//The sell method is a common synchronization method } } } //Using Thread mode // new SellTicket01().start() // new SellTicket01().start(); class SellTicket01 extends Thread { private static int ticketNum = 100;//Let multiple threads share ticketNum // public void m1() { // synchronized (this) { // System.out.println("hello"); // } // } @Override public void run() { while (true) { if (ticketNum <= 0) { System.out.println("End of ticket sales..."); break; } //Sleep 50ms, analog try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket" + " Remaining votes=" + (--ticketNum)); } } } //Implementation interface mode class SellTicket02 implements Runnable { private int ticketNum = 100;//Let multiple threads share ticketNum @Override public void run() { while (true) { if (ticketNum <= 0) { System.out.println("End of ticket sales..."); break; } //Sleep 50ms, analog try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket" + " Remaining votes=" + (--ticketNum));//1 - 0 - -1 - -2 } } }
Notes and details
Thread deadlock
Basic introduction
Application cases
Application cases
public static void main(String[] args) { //Simulate deadlock DeadLockDemo A = new DeadLockDemo(true); A.setName("A thread "); DeadLockDemo B = new DeadLockDemo(false); B.setName("B thread "); A.start(); B.start(); }
//thread class DeadLockDemo extends Thread { static Object o1 = new Object();// Ensure that multiple threads share an object. Here, static is used static Object o2 = new Object(); boolean flag; public DeadLockDemo(boolean flag) {//constructor this.flag = flag; } @Override public void run() { //The following business logic analysis //1. if the flag is T, thread A will first obtain / hold the o1 object lock, and then try to obtain the o2 object lock //2. if thread A cannot get the o2 object lock, it will be Blocked //3. if the flag is F, thread B will first obtain / hold the o2 object lock, and then try to obtain the o1 object lock //4. if thread B cannot obtain the o1 object lock, it will be Blocked if (flag) { synchronized (o1) {//Object mutex. The following is the synchronization code System.out.println(Thread.currentThread().getName() + " Enter 1"); synchronized (o2) { // Here you can obtain the monitoring right of the li object System.out.println(Thread.currentThread().getName() + " Enter 2"); } } } else { synchronized (o2) { System.out.println(Thread.currentThread().getName() + " Enter 3"); synchronized (o1) { // Here you can obtain the monitoring right of the li object System.out.println(Thread.currentThread().getName() + " Enter 4"); } } } } }
Release lock
The following operation will release the lock
The following operation will not release the lock
tNum <= 0) {
System.out.println("end of ticket sales...);
break;
}
//Sleep 50ms, analog
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("window" + Thread.currentThread().getName() + "one ticket sold" + "number of remaining tickets =" + (– ticketNum));
}
}
}
//Implementation interface mode
class SellTicket02 implements Runnable {
private int ticketNum = 100;// Let multiple threads share ticketnum
@Override public void run() { while (true) { if (ticketNum <= 0) { System.out.println("End of ticket sales..."); break; } //Sleep 50ms, analog try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket" + " Remaining votes=" + (--ticketNum));//1 - 0 - -1 - -2 } }
}
### Notes and details [External chain picture transferring...(img-egX3v7Wp-1640865302577)] ## Thread deadlock ### Basic introduction [External chain picture transferring...(img-EgzxnY8V-1640865302577)] ### Application cases [External chain picture transferring...(img-E84rIFXo-1640865302577)] ### Application cases ```java public static void main(String[] args) { //Simulate deadlock DeadLockDemo A = new DeadLockDemo(true); A.setName("A thread "); DeadLockDemo B = new DeadLockDemo(false); B.setName("B thread "); A.start(); B.start(); }
//thread class DeadLockDemo extends Thread { static Object o1 = new Object();// Ensure that multiple threads share an object. Here, static is used static Object o2 = new Object(); boolean flag; public DeadLockDemo(boolean flag) {//constructor this.flag = flag; } @Override public void run() { //The following business logic analysis //1. if the flag is T, thread A will first obtain / hold the o1 object lock, and then try to obtain the o2 object lock //2. if thread A cannot get the o2 object lock, it will be Blocked //3. if the flag is F, thread B will first obtain / hold the o2 object lock, and then try to obtain the o1 object lock //4. if thread B cannot obtain the o1 object lock, it will be Blocked if (flag) { synchronized (o1) {//Object mutex. The following is the synchronization code System.out.println(Thread.currentThread().getName() + " Enter 1"); synchronized (o2) { // Here you can obtain the monitoring right of the li object System.out.println(Thread.currentThread().getName() + " Enter 2"); } } } else { synchronized (o2) { System.out.println(Thread.currentThread().getName() + " Enter 3"); synchronized (o1) { // Here you can obtain the monitoring right of the li object System.out.println(Thread.currentThread().getName() + " Enter 4"); } } } } }
Release lock
The following operation will release the lock
[external chain picture transferring... (img-oADZX6Mr-1640865302578)]