Han Shunping Java collection self-study notes (Java 30-day foundation)

Han Shunping Java collection self-study notes

java collection

Collection understanding and benefits

Disadvantages of arrays

(1) The length must be specified at the beginning, and once specified, it cannot be changed.
(2) The saved elements must be of the same type.
(3) It is cumbersome to use an array to add elements.

Array expansion is inflexible and cumbersome. Examples are as follows:

package com.arrayEx;

import org.junit.Test;

/**
 * @author wty
 * @date 2022/10/3 18:18
 * 数组扩容:灵活性差,比较麻烦
 */
public class ArrayExample {
    
    
    @Test
    public void expandArray() {
    
    
        Person[] people = new Person[3];
        // 添加几个元素进去
        people[0] = new Person("小明", 10);
        people[1] = new Person("小刚", 20);
        people[2] = new Person("小红", 30);

        for (Person person : people) {
    
    
            System.out.println(person);
        }

        System.out.println("-----------扩容后----------");

        Person[] peopleAdd = new Person[5];
        for (int i = 0; i < people.length; i++) {
    
    
            peopleAdd[i] = people[i];
        }

        peopleAdd[3] = new Person("梅梅", 40);
        peopleAdd[4] = new Person("兰兰", 50);

        for (Person person : peopleAdd) {
    
    
            System.out.println(person);
        }
    }
}

class Person {
    
    
    private String name;
    private int age;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Benefits of collection

(1) Any number of objects can be saved dynamically, which is more convenient to use
(2) A series of convenient methods for manipulating objects are provided: add, remove, set, get, etc.
(3) Using collections to add and delete new elements is more concise

collection class diagram
collection class diagram

Collection interface diagram
Collection interface diagram

Map interface diagram
Map interface diagram

1. Collections are mainly two groups (single-column collection and double-column collection)
2. The Collection interface has two important sub-interfaces List Set and their implementation subclasses are single-column collections.
3. The implementation subclass of the Map interface is a double-column collection. Stored Key-Value

The characteristics of the Collection interface implementation class

public interface Collection extends Iterable

(1) Collection implementation subclasses can store multiple elements, and each element can be Object
(2) Some Collection implementation classes can store repeated elements, and some cannot
(3) Some Collection implementation classes are ordered ( List), some are unordered (Set) – the ordered and unordered here refers to whether the order of taking out is consistent with the order of putting in (
4) The Collection interface does not have a direct implementation subclass, but through its subinterface Set and List to achieve

Example:

package com.CollectionExercise;

import org.junit.Test;

import java.util.*;

/**
 * @author wty
 * @date 2022/10/3 18:33
 */
public class CollectionExp {
    
    
    @Test
    @SuppressWarnings({
    
    "all"})
    public void knowCollection() {
    
    
        //Collection
        //Map
        //LinkedHashMap
        //ArrayList
        // 创建一个ArrayList(单列集合)
        List list = new ArrayList();
        // add添加单个元素
        list.add("hello");
        list.add(10); // list.add(new Integer(10))
        list.add(true);
        list.add(new Integer(30));
        list.add(new String("word"));
        System.out.println(list);

        // remove删除元素
        list.remove(0);// 删除第一个元素hello
        list.remove("word"); //指定删除对象
        System.out.println(list);

        // contains查找某个元素是否存在
        System.out.println(list.contains(true));
        System.out.println(list.contains("hello"));

        // size获取元素个数
        System.out.println("size:" + list.size());

        // isEmpty是否为空
        System.out.println(list.isEmpty());

        // clear清空
        list.clear();
        System.out.println(list);

        // addAll 可以添加集合、多个元素
        List list2 = new ArrayList();
        list2.add(35.5d);
        list2.add(45.5f);
        list.addAll(list2);
        System.out.println(list);

        // containsAll 查找多个元素是否存在
        System.out.println(list.containsAll(list2));

        // removeall 删除多个元素
        List list3 = new ArrayList();
        list3.add("特别的爱特别的你");
        list.addAll(list3);
        System.out.println("removeall前:" + list);

        list.removeAll(list3);
        System.out.println("removeall后:" + list);

    }
}

The traversal form of the Collection interface

Use iterator Iterator (iterator)

(1) The Itrator object is called an iterator, as long as it is used to traverse the elements in the Collection.
(2) All collection classes that implement the Collection interface have an Iterator() method to return an object that implements the Iterator interface, that is, an iterator can be returned (3) Iterator is only used to traverse the
collection, and Iterator itself does not storage object

How iterators work

How iterators work

Methods of the Itrator interface

Methods of the Itrator interface

Example:

package com.ItratorExercise;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author wty
 * @date 2022/10/4 11:45
 */
public class ItratorExercise {
    
    
    @Test
    @SuppressWarnings({
    
    "all"})
    public void getItrator() {
    
    
        Collection arrayList = new ArrayList();
        arrayList.add(new Book("三国演义", "罗贯中", 42.99));
        arrayList.add(new Book("西游记", "吴承恩", 38.5));
        arrayList.add(new Book("水浒传", "施耐庵", 66.66));

        System.out.println("直接输出:" + arrayList);
        System.out.println("------------------");

        // 先得到对应的迭代器
        Iterator iterator = arrayList.iterator();
        // 快捷键itit
        // ctrl + j :所有快捷键的快捷键

        while (iterator.hasNext()) {
    
     // 判断是否还有数据
            // 返回下一个元素,类型是Object
            Object next = iterator.next();
            System.out.println(next);
        }

        // 当退出while循环后,这时迭代器指向最后一个元素
        //报错 iterator.next(); // java.util.NoSuchElementException

        // 如果希望再次遍历,需要重置迭代器
        arrayList.add("今天天气不错");
        System.out.println("重置迭代器之后………………");
        iterator = arrayList.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();
            System.out.println(next);
        }
    }
}

class Book {
    
    
    private String name;
    private String author;
    private double price;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getAuthor() {
    
    
        return author;
    }

    public void setAuthor(String author) {
    
    
        this.author = author;
    }

    public double getPrice() {
    
    
        return price;
    }

    public void setPrice(double price) {
    
    
        this.price = price;
    }

    public Book(String name, String author, double price) {
    
    
        this.name = name;
        this.author = author;
        this.price = price;
    }

    @Override
    public String toString() {
    
    
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }
}

for loop enhanced traversal

The enhanced for loop can replace the itrator iterator, features: the enhanced for is a simplified version of iterator, the essence is the same. Can only be used to traverse collections or arrays

Basic syntax:

for(元素类型 元素名:集合名或数组名){
    
    
 访问元素
}

Example:

package com.StrongFor;

import org.junit.Test;

import java.util.ArrayList;

/**
 * @author wty
 * @date 2022/10/4 14:18
 */
public class StrongFor {
    
    
    @Test
    public void strongFor() {
    
    

        ArrayList arrayList = new ArrayList();
        arrayList.add(new Teacher("王老师", 45, 1.68));
        arrayList.add(new Teacher("李老师", 25, 1.58));
        arrayList.add(new Teacher("刘老师", 27, 1.78));

        // 使用增强for循环,在Collection集合
        // 底层仍然是迭代器
        // 增强for循环,可以理解成简化版的迭代器
        // I快捷键
        for (Object o : arrayList) {
    
    
            System.out.println(o);
        }


        // 增强for循环也可以在数组使用
        int[] nums = {
    
    1, 8, 9, 10};
        for (int num : nums) {
    
    
            System.out.println(num);
        }

    }
}

class Teacher {
    
    
    private String name;
    private int age;
    private double height;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public double getHeight() {
    
    
        return height;
    }

    public void setHeight(double height) {
    
    
        this.height = height;
    }

    public Teacher(String name, int age, double height) {
    
    
        this.name = name;
        this.age = age;
        this.height = height;
    }

    @Override
    public String toString() {
    
    
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}

Class practice:

Write a program CollectionExercise
(1) Create 3 Dog {name, age} objects, put them into ArrayList, and assign them to List to use (
2) Use iterators and enhanced for loops to traverse
(3) Rewrite Dog's toString method, output name and age

package com.CollectionAndIterator;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author wty
 * @date 2022/10/4 14:33
 */
public class CollectionExerciseAndIterator {
    
    
    @Test
    public void cllectionExerciseAndIterator() {
    
    
        List list = new ArrayList();
        list.add(new Dog("大黄", 1));
        list.add(new Dog("小贝", 2));
        list.add(new Dog("来福", 3));

        // 迭代器
        System.out.println("迭代器");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();
            System.out.println(next);
        }

        System.out.println("增强for循环");
        // 增强for循环
        for (Object o : list) {
    
    
            System.out.println(o);
        }

    }
}

class Dog {
    
    
    private String name;
    private int age;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public Dog(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

List interface and common methods

The List interface is a subinterface of the Collection interface

(1) The elements in the List collection class are ordered (that is, the order of adding and taking out is the same), and can be repeated
(2) Each element in the List collection has its corresponding order index, which supports indexing
(3) In the List container Each element corresponds to an integer serial number to record its position in the container, and the elements in the container can be accessed according to the serial number.
(4) The common implementation classes of the List interface are: ArrayList, LinkedList and Vector

List interface and common methods
(1) add inserts an element at the index position
(2) addAll adds all elements from the index position
(3) get obtains the element at the specified index position
(4) indexOf returns the first occurrence position in the collection
( 5) lastIndexOf returns the last position in the current collection
(6) remove removes the element at the index position and returns this element
(7) set sets the element at the specified index position (replacement)
(8) subList returns a range of positions sub-collection

Example:

package com.ListExercise;
	
	import org.junit.Test;
	
	import java.util.ArrayList;
	import java.util.List;
	
	/**
	 * @author wty
	 * @date 2022/10/4 15:04
	 */
	public class ListMethod {
    
    
	    @Test
	    public void ListMethodExercise() {
    
    
	        List list = new ArrayList();
	        list.add("张三丰");
	        list.add("贾宝玉");
	
	        // 插入一个元素
	        list.add(1, "林黛玉");
	        System.out.println(list);
	
	        // 插入一个集合
	        List list2 = new ArrayList();
	        list2.add("Jack");
	        list2.add("Tom");
	        list.addAll(1, list2);
	        System.out.println(list);
	
	        // 获取集合中索引的值
	        System.out.println("get(2):" + list.get(2)); // Tom
	
	        // 返回首个出现的位置
	        System.out.println(list.indexOf("林黛玉")); // 3
	
	        // 返回末次出现的位置
	        list.add("林黛玉");
	        System.out.println(list.lastIndexOf("林黛玉")); // 5
	
	        // 移除元素并且输出该元素
	        list.remove(5);
	        System.out.println(list);
	
	        // 替换
	        list.set(1, "王宝强");
	        System.out.println(list);
	
	        // 返回范围值内的子集合[0,3)所以只有0,1,2三个元素
	        List listReturn = list.subList(0, 3);
	        System.out.println(listReturn);
	    }
	}

practise:

package com.ListExercise;
	
	import org.junit.Test;
	
	import java.util.ArrayList;
	import java.util.Iterator;
	import java.util.List;
	
	/**
	 * @author wty
	 * @date 2022/10/4 15:17
	 */
	public class ListExercise02 {
    
    
	    @Test
	    public void ListExer02() {
    
    
	        List list = new ArrayList();
	        list.add("1 你好");
	        list.add("2 hello world");
	        list.add("3 10");
	        list.add("4 今天天气不错");
	        list.add("5 开心");
	        list.add("6 难过");
	        list.add("7 悲伤");
	        list.add("8 喜悦");
	        list.add("9 幸福");
	        list.add("10 自豪");
	        System.out.println(list);
	
	        list.add(1, "韩顺平教育");
	        System.out.println("在2号位置插入:" + list);
	
	        System.out.println("获取第5个元素:" + list.get(4));
	        list.remove(5);
	        System.out.println("删除第6个元素后:" + list);
	        list.set(6, "很悲伤");
	        System.out.println("修改第7个元素后:" + list);
	
	
	        Iterator iterator = list.iterator();
	        while (iterator.hasNext()) {
    
    
	            Object next = iterator.next();
	            System.out.println(next);
	        }
	    }
	}

Three traversal methods of List

(1) Method 1: Use an iterator
(2) Method 2: Enhance the for loop
(3) Method 3: Use a normal for loop

package com.ListExercise;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

/**
 * @author wty
 * @date 2022/10/4 18:08
 */
public class Bianli {
    
    
    @Test
    public void getBianli() {
    
    
        List list = new ArrayList();
        list.add("Jack");
        list.add("Tom");
        list.add("鱼香肉丝");
        list.add("北京烤鸭");

        // 迭代器遍历
        System.out.println("-----迭代器遍历:-----");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();
            System.out.println(next);
        }

        // 增强for循环遍历
        System.out.println("------增强for循环遍历:-------");
        for (Object o : list) {
    
    
            System.out.println(o);
        }

        // 普通for循环遍历(类似数组)
        System.out.println("-----普通for循环遍历:-------");
        for (int i = 0; i < list.size(); i++) {
    
    
            System.out.println(list.get(i));
        }

    }

    @Test
    public void getBianli02() {
    
    
        List vector = new Vector();
        vector.add("Jack");
        vector.add("Tom");
        vector.add("鱼香肉丝");
        vector.add("北京烤鸭");

        // 迭代器遍历
        System.out.println("-----迭代器遍历:-----");
        Iterator iterator = vector.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();
            System.out.println(next);
        }

        // 增强for循环遍历
        System.out.println("------增强for循环遍历:-------");
        for (Object o : vector) {
    
    
            System.out.println(o);
        }

        // 普通for循环遍历(类似数组)
        System.out.println("-----普通for循环遍历:-------");
        for (int i = 0; i < vector.size(); i++) {
    
    
            System.out.println(vector.get(i));
        }

    }
}

Class Exercise 2

insert image description here

Bubble sort sorts a property of objects in a collection

package com.ListExercise;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wty
 * @date 2022/10/4 18:19
 */
public class ListExercise03 {
    
    
    @Test
    public void listExercise03() {
    
    
        List list = new ArrayList();
        list.add(new Book("红楼梦", 100, "曹雪芹"));
        list.add(new Book("西游记", 10, "吴承恩"));
        list.add(new Book("水浒传", 9, "施耐庵"));
        list.add(new Book("三国演义", 80, "罗贯中"));
        list.add(new Book("西游记", 10, "吴承恩"));

        // 正常顺序
        System.out.println("-----正常顺序-----");
        for (int i = 0; i < list.size(); i++) {
    
    
            System.out.println(list.get(i));
        }

        // 冒泡排序之后的顺序,从小到大
        BubbleSort(list);

        System.out.println("-----冒泡排序之后-------");
        for (int i = 0; i < list.size(); i++) {
    
    
            System.out.println(list.get(i));
        }
    }

    public void BubbleSort(List list) {
    
    
        int size = list.size();
        for (int i = 0; i < size - 1; i++) {
    
    
            for (int j = 0; j < size - i - 1; j++) {
    
    
                Object ob1 = list.get(j);
                Object ob2 = list.get(j + 1);
                // 向下转型
                Book book1 = (Book) ob1;
                Book book2 = (Book) ob2;

                if (book1.getPrice() > book2.getPrice()) {
    
    
                    list.set(j + 1, book1);
                    list.set(j, book2);
                }
            }

        }
    }
}

class Book {
    
    
    private String name;
    private double price;
    private String author;

    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;
    }

    public String getAuthor() {
    
    
        return author;
    }

    public void setAuthor(String author) {
    
    
        this.author = author;
    }

    public Book(String name, double price, String author) {
    
    
        this.name = name;
        this.price = price;
        this.author = author;
    }

    @Override
    public String toString() {
    
    
        return "名称:'" + name + '\'' +
                ", 价格:" + price +
                ", 作者:'" + author + '\'';
    }
}

ArrayList underlying structure and source code analysis

(1).ArrayList can hold all elements or even empty elements, and can hold multiple empty values.
(2).ArrayList implements data storage by an array .
(3).ArrayList is basically equivalent to Vector, except that ArrayList is not thread-safe (high execution efficiency). Under multi-threading, it is not recommended to use ArrayList.
(4).ArrayList maintains an array of Object type elementData
transient Object[] elementData
transient: short, instant, indicating that the property will not be serialized
(5). When creating an ArrayList object, if you use None If you refer to the constructor, the initial elementData capacity is 0. When you add it for the first time, expand the elementData to 10. If you need to expand again, expand the elementData to 1.5 times (
6). If you use a constructor with a specified size, the initial elementData The capacity is the specified size, if expansion is required, directly expand elementData to 1.5 times

Vector underlying structure and source code analysis

Basic introduction to Vector

(1) Definition of Vector class:
public class Vector
extends AbstractList
implements List, RandomAccess, Cloneable, Serializable
(2) The bottom layer of Vector is also an array of objects, protected Object[] elementData
(3) Vector is thread-synchronized, that is, thread-safe, The operation method of the Vector class has synchronized
(4) During development, when thread synchronization safety is required, Vector is given priority

Comparison of Vector and List

LinkedList underlying structure

(1) LinkedList implements the characteristics of doubly linked list and double-ended queue
(2) Any element can be added (element can be repeated), including null
(3) Thread is not safe and synchronization is not implemented

The underlying operation mechanism of LinkedList

(1) The bottom layer of LinkedList maintains a doubly linked list
(2) LinkedList maintains two attributes first and last pointing to the first node and last node respectively
(3) Each node (Node object) maintains prev, next, item inside Three attributes, where prev points to the previous node, and next points to the next node, and finally realizes the doubly linked list.
(4) Therefore, the addition and deletion of elements of LinkedList is not done through arrays, which is relatively efficient
The underlying operation mechanism of LinkedList

Simulate a simple example of a doubly linked list:

package com.ListExercise;

import org.junit.Test;

/**
 * @author wty
 * @date 2022/10/6 14:45
 * 模拟一个双向链表
 */
public class LinkedListExercise02 {
    
    
    @Test
    public void getLinked() {
    
    
        Linked one = new Linked("One");
        Linked two = new Linked("Two");
        Linked four = new Linked("Four");


        one.next = two;
        two.next = four;

        four.pre = two;
        two.pre = one;

        Linked first = one; // 定义头结点
        System.out.println("----从头到尾遍历-----");
        while (true) {
    
    
            if (first == null) {
    
    
                break;
            }
            System.out.println(first);
            first = first.next;
        }

        Linked last = four; // 定义尾结点
        System.out.println("----从尾到头遍历-----");
        while (true) {
    
    
            if (last == null) {
    
    
                break;
            }
            System.out.println(last);
            last = last.pre;
        }

        // 插入一个元素
        Linked three = new Linked("Three");
        two.next = three;
        four.pre = three;

        three.next = four;
        three.pre = two;

        first = one;
        System.out.println("插入元素3之后,从头到尾遍历");
        while (true) {
    
    
            if (null == first) {
    
    
                break;
            }
            System.out.println(first);
            first = first.next;
        }

        last = four;
        System.out.println("插入元素3之后,从尾到头遍历");
        while (true) {
    
    
            if (null == last) {
    
    
                break;
            }
            System.out.println(last);
            last = last.pre;
        }


    }
}

class Linked {
    
    
    public Linked pre;
    public Linked next;
    public Object name;

    public Linked(Object name) {
    
    
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "Linked{" +
                "name=" + name +
                '}';
    }
}

About LinkedList source code analysis

package com.ListExercise;

import org.junit.Test;

import java.util.Iterator;
import java.util.LinkedList;

/**
 * @author wty
 * @date 2022/10/6 15:01
 */
public class LinkedListCRUD {
    
    
    @Test
    public void linkedListCRUD() {
    
    
        LinkedList list = new LinkedList();
        list.add(100);
        list.add(200);
        list.add(300);
        System.out.println(list);

        // 修改,把200更改成400
        System.out.println(list.set(1, 400)); // 200

        // 删除400
        System.out.println(list.remove(1)); // 400

        // 查找第2个元素
        System.out.println(list.get(1));

        // 迭代器遍历
        System.out.println("----迭代器遍历----");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();
            System.out.println(next);
        }

        System.out.println("增强for循环遍历");
        for (Object o : list) {
    
    
            System.out.println(o);
        }

        System.out.println("普通for循环遍历");
        for (int i = 0; i < list.size(); i++) {
    
    
            System.out.println(list.get(i));
        }

    }
}

The difference between LinkedList and ArrayList

The difference between LinkedList and ArrayList

Set interface and common methods

(1) Unordered (inconsistent order of adding and taking out), no index
(2) Duplicate elements are not allowed, so at most one null is included
(3) The implementation classes of the Set interface in the JDK API are:

The traversal method of the Set interface

It is the same as the traversal method of Collection, because the Set interface is a sub-interface of the Collection interface.
1. You can use iterators
2. Enhance the for loop
3. Cannot use the index method to obtain

Examples of common methods;

package com.SetExercise;

import org.junit.Test;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * @author wty
 * @date 2022/10/6 17:24
 */
public class SetMethod {
    
    
    @Test
    public void SetMethodEx() {
    
    
        // 以Set接口的实现类,HashSet为例
        // Set接口的实现类的对象(Set接口对象)不能存放重复元素
        // 可以添加一个null
        // Set接口对象存放数据、对象是无序的(添加顺序和取出顺序不一致)
        // 取出的顺序是固定的
        Set set = new HashSet();
        set.add("小明");
        set.add("小芳");
        set.add("小刚");
        set.add("小明");
        set.add(null);
        set.add(null);
        System.out.println(set);

        // 遍历
        //方式1;迭代器
        System.out.println("---迭代器---");
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();
            System.out.println(next);
        }

        // 增强for循环
        System.out.println("---增强for循环---");
        for (Object o : set) {
    
    
            System.out.println(o);
        }

        System.out.println("size:" + set.size());
        System.out.println("是否为空:" + set.isEmpty());
        System.out.println("是否包含元素[小刚]:" + set.contains("小刚"));
        System.out.println("remove:" + set.remove("小刚"));
        System.out.println("remove:" + set.remove(null));
        System.out.println(set);
    }
}

A comprehensive description of HashSet

(1) HashSet implements the Set interface
(2) HashSet is actually a HashMap
(3) can store null values, but there can only be one null
(4) HashSet does not guarantee that the elements are in order, depending on the hash, then determine the index The result (the order of storage and retrieval of elements is not guaranteed to be consistent)
(5) There cannot be duplicate elements/objects. The use of the Set interface has already been mentioned in the front

package com.SetExercise;

import org.junit.Test;

/**
 * @author wty
 * @date 2022/10/6 18:14
 */
public class HashSetStructure {
    
    
    @Test
    public  void getHashSetStr(){
    
    
        // 模拟一个HashSet的底层(其实就是HashMap)
        // 创建一个Node数组,有些人称为table
        Node[] table = new Node[16];
        System.out.println("table:" + table);
        // 把john放在2的位置
        Node jhon = new Node("Jhon",null);
        table[2] = jhon;
        System.out.println("table:" + table);

        Node jack = new Node("Jack", null);
        jhon.next = jack; // 将jack挂载到johj后边
        System.out.println("table:" + table);

        // 继续把Rose挂载到Jack后面
        Node rose = new Node("Rose", null);
        jack.next = rose;
        System.out.println("table:" + table);

        // 把Lucy放到table表索引为3的位置
        Node lucy = new Node("Lucy", null);
        table[3] = lucy;

    }
}
// 结点,存储数据,可以指向下一个结点
class Node{
    
    
    Object item;// 存放数据
    Node next; // 指向下一个结点

    public Node(Object item, Node next) {
    
    
        this.item = item;
        this.next = next;
    }
}

The underlying mechanism of HashSet

Analysis: The bottom layer of HashSet is HashMap, and the bottom layer of HashMap is (array + linked list + red-black tree)
condensed into 6 sentences

  1. The bottom layer of HashSet is HashMap
  2. When adding an element, first get the hash value, which will be converted into an index value
  3. Find the storage data table table to see if there are elements stored in this index position
  4. If not, just join
  5. If there is, call equals to compare, if it is the same, give up adding, if not, add it to the end
  6. In JAVA 8, if the number of elements in a linked list reaches TREEIFY_THRESHOLD (default is 8), and the size of the table is >= MIN_TREEIFY_CAPACITY (default 64), it will be treed (red-black tree)
    The underlying mechanism of HashSet
    The underlying mechanism of HashSet

classroom exercises

classroom exercises

Homework

equals and hashCode Example 1:
equals和hashCode

package com.SetExercise;

import org.junit.Test;

import java.util.HashSet;
import java.util.Objects;

/**
 * @author wty
 * @date 2022/10/7 14:50
 */
public class Employee {
    
    
    @Test
    public void employee() {
    
    
        HashSet hashSet = new HashSet();
        hashSet.add(new Workers("小明", 10));
        hashSet.add(new Workers("小红", 20));
        hashSet.add(new Workers("小明", 30));
        hashSet.add(new Workers("小刚", 40));
        hashSet.add(new Workers("小明", 10));
        System.out.println("size:" + hashSet.size());
        System.out.println(hashSet);
    }
}

class Workers {
    
    
    private String name;
    private int age;

    public Workers(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Workers{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    // 如果name和age相同,要返回相同的哈希值
    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Workers workers = (Workers) o;
        return Objects.equals(name, workers.name) && this.age == workers.age;
    }

/*    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Workers workers = (Workers) o;
        return age == workers.age && Objects.equals(name, workers.name);
    }*/

    @Override
    public int hashCode() {
    
    
        return Objects.hash(name, age);
    }
}

equals and hashCode example 2: rewrite 2 times

package com.SetExercise;

import org.junit.Test;

import java.util.Date;
import java.util.HashSet;
import java.util.Objects;

/**
 * @author 心向阳光的天域
 * @date 2022/10/7 15:19
 */
public class Employee02 {
    
    
    @Test
    public void getPerson() {
    
    
        HashSet hashSet = new HashSet();
        hashSet.add(new Employ("小明", 10000.88d, new MyDate("1996", "01", "01")));
        // 姓名一样,出生年份不同
        hashSet.add(new Employ("小明", 10001.88d, new MyDate("1997", "01", "01")));
        // 出生年份和工资不同
        hashSet.add(new Employ("小明", 10001.88d, new MyDate("1998", "01", "01")));
        // 工资和第一个比不同(按照规则,这个应该不展示)
        hashSet.add(new Employ("小明", 10002.88d, new MyDate("1996", "01", "01")));

        // 重写了toString()方法,这里可以遍历一下,看看值
        System.out.println("size:" + hashSet.size());
        for (Object o : hashSet) {
    
    
            System.out.println(o);
        }
    }
}

class Employ {
    
    
    private String name;
    private double sal;
    private MyDate birthday;

    public Employ(String name, double sal, MyDate birthday) {
    
    
        this.name = name;
        this.sal = sal;
        this.birthday = birthday;
    }

    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employ employ = (Employ) o;
        return Objects.equals(name, employ.name) && Objects.equals(birthday, employ.birthday);
    }

    @Override
    public int hashCode() {
    
    
        return Objects.hash(name, birthday);
    }

    @Override
    public String toString() {
    
    
        return "Employ{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", birthday=" + birthday +
                '}';
    }
}

class MyDate {
    
    
    String year;
    String month;
    String day;

    public MyDate(String year, String month, String day) {
    
    
        this.year = year;
        this.month = month;
        this.day = day;
    }

    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyDate myDate = (MyDate) o;
        return Objects.equals(year, myDate.year) && Objects.equals(month, myDate.month) && Objects.equals(day, myDate.day);
    }

    @Override
    public int hashCode() {
    
    
        return Objects.hash(year, month, day);
    }

    @Override
    public String toString() {
    
    
        return "MyDate{" +
                "year='" + year + '\'' +
                ", month='" + month + '\'' +
                ", day='" + day + '\'' +
                '}';
    }
}

equals and hashCode example 2: rewrite 1 time

package com.SetExercise;

import org.junit.Test;

import java.util.Date;
import java.util.HashSet;
import java.util.Objects;

/**
 * @author 心向阳光的天域
 * @date 2022/10/7 15:19
 */
public class Employee03 {
    
    
    @Test
    public void getPerson() {
    
    
        HashSet hashSet = new HashSet();
        hashSet.add(new Employ("小明", 10000.88d, new MyDate("1996", "01", "01")));
        hashSet.add(new Employ("小明", 10001.88d, new MyDate("1997", "01", "01")));
        hashSet.add(new Employ("小明", 10001.88d, new MyDate("1998", "01", "01")));
        // 按照重复数据去重
        hashSet.add(new Employ("小明", 10002.88d, new MyDate("1996", "01", "01")));

        System.out.println("size:" + hashSet.size());
        for (Object o : hashSet) {
    
    
            System.out.println(o);
        }
    }
}

class Employ02 {
    
    
    private String name;
    private double sal;
    private MyDate02 birthday;

    public Employ02(String name, double sal, MyDate02 birthday) {
    
    
        this.name = name;
        this.sal = sal;
        this.birthday = birthday;
    }

    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employ02 employ = (Employ02) o;
        return Objects.equals(name, employ.name)
                // 这里直接重写一次equals方法即可
                && Objects.equals(birthday.getYear(), employ.birthday.getYear())
                && Objects.equals(birthday.getMonth(), employ.birthday.getMonth())
                && Objects.equals(birthday.getDay(), employ.birthday.getDay());
    }

    @Override
    public int hashCode() {
    
    
        // 这里直接重写一次hashCode方法即可
        return Objects.hash(name, birthday.year, birthday.month, birthday.day);
    }

    @Override
    public String toString() {
    
    
        return "Employ{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", birthday=" + birthday +
                '}';
    }
}

class MyDate02 {
    
    
    String year;
    String month;
    String day;

    public MyDate02(String year, String month, String day) {
    
    
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public String getYear() {
    
    
        return year;
    }

    public void setYear(String year) {
    
    
        this.year = year;
    }

    public String getMonth() {
    
    
        return month;
    }

    public void setMonth(String month) {
    
    
        this.month = month;
    }

    public String getDay() {
    
    
        return day;
    }

    public void setDay(String day) {
    
    
        this.day = day;
    }

    @Override
    public String toString() {
    
    
        return "MyDate{" +
                "year='" + year + '\'' +
                ", month='" + month + '\'' +
                ", day='" + day + '\'' +
                '}';
    }
}

LinkedHashSet

Comprehensive description of LinkedHashSet
(1) LinkedHashSet is a subclass of HashSet
(2) The bottom layer of LinkedHashSet is a LinkedHashMap, which maintains an array + doubly linked list
(3) LinkedHashSet determines the storage location of elements according to the hashCode value of the element, and uses the linked list to maintain An order map (graph) of elements , which makes elements appear to be stored in insertion order.
(4) LinkedHashSet does not allow adding duplicate elements

illustrate:

  1. Maintain a hash table and a doubly linked list in LinkedHashSet (LinkedHashSet has head and tail)

  2. Each node has before and after attributes, which can form a doubly linked list

  3. When adding an element, first find the hash value, then find the index, determine the position of the element in the table, and then add the added element to the doubly linked list (if it already exists, do not add it [the principle is the same as hashset])

    tail.next = newElement
    newElement.pre = tail
    tail = newElement;

  4. In this way, we can also ensure that the insertion order and the traversal order are consistent when traversing the LinkedHashSet

equals and hashCode rewriting

package com.SetExercise;

import org.junit.Test;

import java.util.LinkedHashSet;
import java.util.Objects;

/**
 * @author wty
 * @date 2022/10/8 19:57
 * 如果name和price一样就认为是一样的元素
 */
public class LinkedHashSetExercise01 {
    
    

    @Test
    public void getHashSet() {
    
    
        LinkedHashSet set = new LinkedHashSet();
        set.add(new Car("奥迪", 1000d));
        set.add(new Car("奥迪", 30000d));
        set.add(new Car("法拉利", 100000d));
        set.add(new Car("保时捷", 7000000d));
        set.add(new Car("奥迪", 1000d));


        for (Object o : set) {
    
    
            System.out.println(o);
        }
    }
}

class Car {
    
    
    private String name;
    private double price;

    public Car(String name, double price) {
    
    
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
    
    
        return "Car{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    // 重写equals和hash方法
    @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);
    }
}

Map collection

Features of the Map interface implementation class

(1) Map and Collection exist side by side, and are used to store data with mapping relationship Key-Value (double-column elements)
(2) The key and value in Map can be any reference type of data, which will be encapsulated into the HashMap$Node object
(3) The key in the Map is not allowed to be repeated. The reason is the same as that of the HashSet. The source code has been analyzed earlier.
(4) The value in the Map can be repeated
(5) The key of the Map can be null, and the value can also be null. Note that if the key is null, there can only be one, and the value can be multiple.
(6) The String class is commonly used as a Map key
(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
(8) Map key-value diagram for storing data, a pair of key-value is placed in a Node Among them, because Node implements the Entry interface, some books also say that a pair of key-value is an Entry (as shown in the figure)

package com.Map;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author wty
 * @date 2022/10/8 22:45
 */
public class MapExercise {
    
    
    @Test
    public void getExercise() {
    
    
        // Map接口具有的特点
        // 常用String类作为Map的key
        Map hashMap = new HashMap();
        hashMap.put("1", "Jack");
        hashMap.put("2", 10);
        hashMap.put("3", "贾斯汀比伯");
        hashMap.put("4", "迈克尔杰克逊");
        hashMap.put("5", "贾斯汀比伯");
        hashMap.put("6", "Alice");
        hashMap.put("7", "VERTGA");
        hashMap.put("8", "LAM");
        hashMap.put("9", "GIN");
        hashMap.put("10", "TIO");
        hashMap.put("11", "AIO");
        hashMap.put("12", "Tony");
        hashMap.put("13", "Joy");
        hashMap.put("1", "Rose"); // 替换机制:当有相同key值时。就替换
        hashMap.put(null, null);
        hashMap.put(null, null); // Map的key可以为null,value也可以为null,注意key为null,只能有一个,value为null可以多个
        hashMap.put("17", null);
        hashMap.put(null, 181); // 替换
        hashMap.put(1, "Jack"); // key可以用别的类型

        System.out.println(hashMap);
        System.out.println("get(1):" + hashMap.get(1));


    }
}

entrySet() obtains entrySet, entrySet is a Set<Entry<key, value> interface, which stores Entry objects, which store key references and value references

Common methods of Map

(1) put: add
(2) remove: delete the mapping relationship according to the key
(3) get: obtain the value according to the key
(4) size: obtain the number of elements
(5) isEmpty: determine whether the number is 0
(6) clear: Clear
(7) containsKey: Find whether the key exists

package com.Map;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author wty
 * @date 2022/10/9 9:02
 */
public class MapUse {
    
    
    @Test
    public void mapUse() {
    
    
        /**
         * (1)put:添加
         * (2)remove:根据键删除映射关系
         * (3)get:根据键获取值
         * (4)size:获取元素个数
         * (5)isEmpty:判断个数是否为0
         * (6)clear:清除
         * (7)containsKey:查找键是否存在
         */

        Map map = new HashMap();
        map.put("1", "Book");
        map.put("邓超", "孙俪");
        map.put("马蓉", "王宝强");
        map.put("马蓉", "宋喆");

        System.out.println(map);

        map.remove("1");
        System.out.println(map);

        System.out.println(map.get("邓超"));

        System.out.println("size:" + map.size());

        System.out.println("是否为空:" + map.isEmpty());

        System.out.println("有没有马蓉: " + map.containsKey("马蓉"));

        map.clear();
        System.out.println("clean之后" + map);


    }
}

Map interface traversal method

Schematic diagram of Map traversal (a little more complicated than List and Set, but the basic principle is the same)
(1) containsKey: find out whether the key exists
(2) keySet: get all the keys
(3) entrySet: get all the relationships
(4) values: get all values

package com.Map;
	
	import org.junit.Test;
	
	import java.util.*;
	
	/**
	 * @author wty
	 * @date 2022/10/9 9:15
	 */
	public class MapBl {
    
    
	    @Test
	    public void Mapbl() {
    
    
	        Map map = new HashMap();
	        map.put("1", "Jack");
	        map.put("上单", "老夫子");
	        map.put("中单", "诸葛亮");
	        map.put("射手", "后裔");
	        System.out.println(map);
	
	        // 遍历(自己想的)
	        System.out.println("----增强for循环----");
	        Set set = map.entrySet();
	        for (Object o : set) {
    
    
	            System.out.println(o);
	        }
	
	        // 遍历(自己想的)
	        System.out.println("----迭代器----");
	        Iterator iterator = map.entrySet().iterator();
	        while (iterator.hasNext()) {
    
    
	            Object next = iterator.next();
	            System.out.println(next);
	        }
	
	
	        // 韩老师讲的
	        // 1. 先取出所有的key,通过key找到对应的value
	        System.out.println("----map.keySet()----");
	        Set keyset = map.keySet();
	        for (Object o : keyset) {
    
    
	            // 向下转型
	            System.out.println("key = " + o + "   value = " + map.get(o));
	
	        }
	
	        // 2.通过迭代器
	        System.out.println("----map.keySet()的迭代器----");
	        Iterator iterator1 = keyset.iterator();
	        while (iterator1.hasNext()) {
    
    
	            Object next = iterator1.next();
	            System.out.println("key = " + next + "   value = " + map.get(next));
	        }
	
	        // 3.只是把所有的values取出
	        System.out.println("----map.values()----");
	        Collection values = map.values();
	        for (Object value : values) {
    
    
	            System.out.println("value = " + value);
	        }
	
	        System.out.println("----map.values()迭代器----");
	        Iterator iterator2 = values.iterator();
	        while (iterator2.hasNext()) {
    
    
	            Object next = iterator2.next();
	            System.out.println("value = " + next);
	        }
	
	        // 3.通过EntrySet
	        // 增强for循环
	        System.out.println("----map.entrySet()增强for循环----");
	        Set entryset = map.entrySet();
	        for (Object o : entryset) {
    
    
	            Map.Entry entry = (Map.Entry) o;
	            System.out.println("key = " + entry.getKey() + "  value = " + entry.getValue());
	
	        }
	
	
	        // 通过迭代器
	        System.out.println("----entrySet迭代器----");
	        Set entrySet = map.entrySet();
	        Iterator iterator3 = entrySet.iterator();
	        while (iterator3.hasNext()) {
    
    
	            Object next = iterator3.next();
	            //System.out.println(next.getClass()); // HashMap$Node
	
	            Map.Entry entry = (Map.Entry) next;
	            System.out.println("key = " + entry.getKey() + "  value = " + entry.getValue());
	        }
	    }
	}

Homework

Homework

package com.Map;

import org.junit.Test;

import java.util.*;

/**
 * @author wty
 * @date 2022/10/9 12:41
 */
public class AfterClassExercise {
    
    
    @Test
    public void showWorkers() {
    
    
        /*HashSet hashSet = new HashSet();
        hashSet.add(new Workers("王晓亮", 15000.5, "no.1"));
        hashSet.add(new Workers("钟飞扬", 16060.5, "no.2"));
        hashSet.add(new Workers("潘长江", 18060.5, "no.3"));
        hashSet.add(new Workers("小悦悦", 27060.5, "no.4"));
        System.out.println(hashSet);

        for (Object o : hashSet) {
            Map.Entry entry = (Map.Entry) o;
            entry.getKey();
        }*/


        HashMap hashMap = new HashMap();
        hashMap.put("no.1", new Workers("王晓亮", 15000.5, "no.1"));
        hashMap.put("no.2", new Workers("钟飞扬", 16060.5, "no.2"));
        hashMap.put("no.3", new Workers("潘长江", 18060.5, "no.3"));
        hashMap.put("no.4", new Workers("小悦悦", 27060.5, "no.4"));
        hashMap.put("no.5", "Jack");

        // 显示工资大于18000的人
        System.out.println("-----------------keySet()------------------");
        Set set = hashMap.keySet();
        for (Object o : set) {
    
     // String
            //System.out.println(o.getClass());
            if (hashMap.get(o) instanceof Workers) {
    
    
                Workers workers = (Workers) hashMap.get(o); // hashMap.get(o) 是对象Workers
                if (workers.getSal() > 18000) {
    
    
                    System.out.println("key = " + o + "   value = " + hashMap.get(o));
                }
            } else {
    
    
                System.out.println("key = " + o + "   value = " + hashMap.get(o));
            }
        }

        // 迭代器
        System.out.println("-----------------keySet()迭代器------------------");
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();
            if (hashMap.get(next) instanceof Workers) {
    
    
                Workers workers = (Workers) hashMap.get(next);
                if (workers.getSal() > 18000) {
    
    
                    System.out.println("key = " + next + "   value = " + hashMap.get(next));
                }
            } else {
    
    
                System.out.println("key = " + next + "   value = " + hashMap.get(next));
            }

        }

        // 使用entrySet()方法
        System.out.println("-----------entrySet()增强for循环-----------");
        Set set1 = hashMap.entrySet();
        for (Object o : set1) {
    
    
            Map.Entry entry = (Map.Entry) o;
            if (entry.getValue() instanceof Workers) {
    
    
                Workers workers = (Workers) entry.getValue();

                if (workers.getSal() > 18000) {
    
    
                    System.out.println("key = " + entry.getKey() + "   value = " + entry.getValue());
                }
            } else {
    
    
                System.out.println("key = " + entry.getKey() + "   value = " + entry.getValue());
            }
        }

    }
}


class Workers {
    
    
    private String name;
    private double sal;
    String id;

    public Workers(String name, double sal, String id) {
    
    
        this.name = name;
        this.sal = sal;
        this.id = id;
    }

    public double getSal() {
    
    
        return sal;
    }

    public void setSal(double sal) {
    
    
        this.sal = sal;
    }

    @Override
    public String toString() {
    
    
        return "Workers{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", id=" + id +
                '}';
    }

}

Summary of HashMap

  1. Common implementation classes of the Map interface: HashMap, Hashtable and Properties
  2. HashMap is the most frequently used implementation class of the Map interface
  3. HashMap stores data in the form of key-value pairs (HashMap$Node type)
  4. The key cannot be repeated, but the value can be repeated, allowing the use of null values ​​and null keys (null keys can only have 1)
  5. If the same key is added, the original key-val will be overwritten, which is equivalent to modification (key will not be replaced, val will be replaced)
  6. Like HashSet, the order of mapping is not guaranteed , because the bottom layer is stored in a hash table.
  7. HashMap does not implement synchronization, so it is not thread-safe, the method does not perform synchronization and mutual exclusion operations, and is not synchronized

HashMap underlying mechanism and source code analysis

(1) The bottom layer of HashMap maintains an array table of Node type, which is null by default
(2) When creating an object, initialize the load factor (loadFactor) to 0.75
(3) When adding a key-value, get it through the hash value of the key The index in the table. Then judge whether there is an element at the index, and if there is no element, add it directly. If there is an element in the index, continue to judge whether the key of the element is equal to the key to be added. If it is equal, replace it with a new val directly. If not, you need to judge whether it is a tree structure or a linked list structure, and make a corresponding response. deal with. If it is found that the capacity is not enough when adding, it needs to be expanded.
(4) For the first addition, the capacity of the table needs to be expanded to 16, and the threshold value (threshold) is 12.
(5) After expansion, the capacity of the table needs to be expanded to twice the original capacity, and the threshold value is twice the original value, that is 24, and so on.
(6) In Java8, if the number of elements in a linked list exceeds TREEIFY_THRESHOLD (default is 8), and the size of the table is >= MIN_TREEIFY_CAPACITY (default 64), it will be treed (red-black tree)

Simulate HashMap triggering expansion and treeing

package com.Map;

import org.junit.Test;

import java.util.*;

/**
 * @author wty
 * @date 2022/10/9 16:41
 */
public class HashMapSource {
    
    
    @Test
    public void getSource() {
    
    
        HashMap hashMap = new HashMap();
        //HashSet hashSet = new HashSet();
        //LinkedHashSet linkedHashSet = new LinkedHashSet();
        hashMap.put(new Cat("小红", 1) , "no1.Jack");
        hashMap.put(new Cat("小红", 2) , "no2.Jack");
        hashMap.put(new Cat("小红", 3) , "no3.Jack");
        hashMap.put(new Cat("小红", 4) , "no4.Jack");
        hashMap.put(new Cat("小红" ,5) , "no5.Jack");
        hashMap.put(new Cat("小红", 6) , "no6.Jack");
        hashMap.put(new Cat("小红", 7) , "no7.Jack");
        hashMap.put(new Cat("小红", 8) , "no8.Jack");
        /**
         * // 从第二次put之后才会进这里,并且第二次循环时 var12 0  第二次循环结束 var12 1 -- 即第三次循环开始 var12 1
         *    所以var12比put的次数少2,一直到put第9的时候,var12 >= 7才会满足
         *                 while(true) {
         *                     if ((var10 = ((HashMap.Node)var7).next) == null) {
         *                         ((HashMap.Node)var7).next = this.newNode(var1, var2, var3, (HashMap.Node)null);
         *                         if (var12 >= 7) {
         *                             this.treeifyBin(var6, var1);
         *                         }
         *                         break;
         *                     }
         *
         *                     if (((HashMap.Node)var10).hash == var1 && ((var11 = ((HashMap.Node)var10).key) == var2 || var2 != null && var2.equals(var11))) {
         *                         break;
         *                     }
         *
         *                     var7 = var10;
         *                     ++var12;
         *                 }
         */
        hashMap.put(new Cat("小红", 9) , "no9.Jack");
        hashMap.put(new Cat("小红", 10) , "no10.Jack");
        hashMap.put(new Cat("小红", 11) , "no11.Jack");
        hashMap.put(new Cat("小红", 12) , "no12.Jack");
        /**
         * if (++this.size > this.threshold) { 所以是第13次put的时候扩容 16 → 32
         *             this.resize();
         *         }
         */
        hashMap.put(new Cat("小红", 13) , "no13.Jack"); //
        hashMap.put(new Cat("小红", 14) , "no14.Jack");



        hashMap.put(new Cat("小蓝", 9) , "no9.Jack"); // 扩容table 32
        hashMap.put(new Cat("小蓝", 10) , "no10.Jack"); // 扩容table 64
        hashMap.put(new Cat("小蓝", 11) , "no11.Jack"); // 将链表转换成红黑树
        //hashMap.put("11", "no111.Jack");
        //hashMap.put("12", "no12.Jack");
        //hashMap.put("13", "no13.Jack"); // 超过12才扩容
/*        hashMap.remove(new Cat("小蓝", 11));
        hashMap.remove(new Cat("小蓝", 10));
        hashMap.remove(new Cat("小蓝", 9));
        hashMap.remove(new Cat("小红", 8));
        hashMap.remove(new Cat("小红", 7));
        hashMap.remove(new Cat("小红", 6));
        hashMap.remove(new Cat("小红", 5));
        hashMap.remove(new Cat("小红", 4)); // 执行完之后剪枝
        hashMap.remove(new Cat("小红", 3));
        hashMap.remove(new Cat("小红", 3));*/

        Set set = hashMap.keySet();
        for (Object o : set) {
    
    
            System.out.println("key = " + o + " value = " + hashMap.get(o));
        }
        System.out.println(hashMap);
    }
}

class Cat {
    
    
    private  String name;
    private  int age;

    public Cat(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int hashCode() {
    
    
        return Objects.hash(100);
    }
}

Map interface implementation class - Hashtable

(1) The stored elements are key-value pairs: KV
(2) The key and value of the hashtable cannot be null, otherwise a NullPointerException will be thrown
(3) The usage of hashTable is basically the same as that of HashMap
(4) HashTable is thread-safe (synchronized), hashMap is thread-unsafe
(5) implement the Map interface

Notice:

  1. The bottom layer has an array Hashtable$Entry[] with an initial size of 11
  2. Critical value threshold = 11 * 0.75 ≈ 8
  3. Expansion: according to its own expansion mechanism
  4. Execution method addEntry(hash, key, value, index); Add key-value pairs and encapsulate them in Entry

Comparison between Hashtable and HashMap

name Version thread safety (synchronization) efficiency Allow null keys and null values
Hashtable 1.2 unsafe high Can
HashMap 1.0 Safety lower Can't

Properties

basic introduction

  1. The Properties class inherits from the Hashtable class and implements the Map interface, which is also a form of key-value pairs to store data.
  2. Its usage characteristics are similar to Hashtable.
  3. Properties can also be used to load data from the xxx.properties file to the Properties class object, and read and modify it.
  4. Explanation: After work, the xxx.properties file is usually used as a configuration file. This knowledge point is given as an example in IO flow. If you are interested, you can read the article first.

The configuration file will not display garbled characters, and it will be uniformly adjusted to UTF-8

PropertiesEx.java

	package com.Map.Properties;
	
	import org.junit.Test;
	
	import java.io.*;
	import java.util.Iterator;
	import java.util.Map;
	import java.util.Properties;
	import java.util.Set;
	
	/**
	 * @author wty
	 * @date 2022/10/9 23:49
	 */
	public class PropertiesEx {
    
    
	    @Test
	    public void propertiesEx() {
    
    
	        Properties properties = new Properties();
	
	        String path = "src/com/Map/File/res.properties";
	
	        BufferedReader bufferedReader = null;
	        BufferedWriter bufferedWriter = null;
	        try {
    
    
	            bufferedReader = new BufferedReader(new FileReader(path));
	            properties.load(bufferedReader);
	            Set<Map.Entry<Object, Object>> entries = properties.entrySet();
	            Iterator<Map.Entry<Object, Object>> iterator = entries.iterator();
	            while (iterator.hasNext()) {
    
    
	                Map.Entry<Object, Object> next = iterator.next();
	                System.out.println("key = " + next.getKey() + " value = " + next.getValue());
	            }
	
	            // 写入
	            bufferedWriter = new BufferedWriter(new FileWriter(path));
	            properties.setProperty("signature", "rose");
	            properties.setProperty("signature", "厉害");
	            properties.store(bufferedWriter, "This is my destney哈哈");
	
	
	        } catch (IOException e) {
    
    
	            e.printStackTrace();
	        } finally {
    
    
	            try {
    
    
	                bufferedReader.close();
	                bufferedWriter.close();
	
	            } catch (IOException e) {
    
    
	                e.printStackTrace();
	            }
	        }
	    }
	}

res.properties

name=root
key=value
pass=liu

basic usage

package com.Map.Properties;

import org.junit.Test;

import java.util.Properties;

/**
 * @author wty
 * @date 2022/10/10 9:46
 */
public class PropertiesExercise {
    
    
    @Test
    public void getEx() {
    
    
        Properties properties = new Properties();
        properties.put("no.1", "Jack");
        properties.put("no.2", "Jone");
        // 有相同的key,value会被替换
        properties.put("no.2", "Joy");
        //properties.put(null,null); // java.lang.NullPointerException
        // 键不能为空
        //properties.put(null,"1"); // java.lang.NullPointerException
        // 值不能为空
        //properties.put("no.3",null); // java.lang.NullPointerException

        properties.put("no.3", "Rose");


        System.out.println(properties);

        // 通过key获取对应的值
        System.out.println("no.2:  " + properties.get("no.2"));

        properties.remove("no.3");
        System.out.println("删除no.3之后");
        System.out.println(properties);


        // 修改:
        properties.setProperty("no.2", "Alice");
        System.out.println("setProperty修改no.2之后");
        System.out.println(properties);

        properties.put("no.2", "Rice");
        System.out.println("putno.2之后");
        System.out.println(properties);

        // 查找
        System.out.println("getProperty no.1之后");
        System.out.println(properties.getProperty("no.1"));
    }
}

Collection selection

In development, the collection implementation class to choose mainly depends on the characteristics of business operations , and then the selection is made according to the characteristics of the collection implementation class. The analysis is as follows:

(1)先判断存储类型(一组对象(单列)或者键值对(双列))  
(2)一组对象: Collection接口  
   允许重复:List  
            增删多:LinkedList(底层是双向链表)  
            查改多:ArrayList(底层维护Object类型的可变数组)  
  不允许重复:Set
            无序:HashSet底层是HashMap,维护一个Hash表(数组+链表+红黑树)  
			排序:TreeSet  
            插入和取出顺序一样: LinkedHashSet(继承自LinkedHashMap),维护数组+双向链表  
(3)键值对:Map
         键无序:HashMap(底层是:哈希表:数组+链表+红黑树)  
		 键有序:TreeMap  
         键插入和取出顺序一致:LinkedHashMap(继承自HashMap)  
 		 读取文件: Properties  

TreeSet

TreeSet Contains Comparator Constructor

package com.SetExercise;

import org.junit.Test;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * @author wty
 * @date 2022/10/10 10:20
 */

public class TreeSetExercise {
    
    
    @Test
    @SuppressWarnings({
    
    "all"})
    public void getTreeSet() {
    
    
        // 当使用无参构造器创建TreeSet的时候是无序的
        TreeSet treeSet = new TreeSet();
        // 添加数据
        treeSet.add("Derrick");
        treeSet.add("Rose");
        treeSet.add("Jam");
        treeSet.add("Timmy");
        treeSet.add("Tom");

        System.out.println(treeSet);


        System.out.println("---字符串按照首字母顺序比较---");
        // 添加的元素按照字符串大小来排序
        // 可以传入一个比较器(匿名内部类),并指定规则
        TreeSet treeSet1 = new TreeSet(new Comparator() {
    
    
            @Override
            public int compare(Object o, Object t1) {
    
    
                return ((String) o).compareTo((String) t1);
            }
        });
        treeSet1.add("Derrick");
        treeSet1.add("Rose");
        treeSet1.add("Jam");
        treeSet1.add("Timmy");
        treeSet1.add("Tom");

        System.out.println(treeSet1);
        // 源码解读
        /**
         *     public TreeMap(Comparator<? super K> var1) {
         *         this.comparator = var1; 把new Comparator() 给到TreeMap的comparator属性
         *     }
         */

        System.out.println("---字符串长度大小比较---");
        TreeSet treeSet2 = new TreeSet(new Comparator() {
    
    
            @Override
            public int compare(Object o, Object t1) {
    
    
                String str_a = (String) o;
                String str_t1 = (String) t1;
                int a = ((String) o).length();
                int b = ((String) t1).length();
                int result = a - b;
                return result = result == 0 ? str_a.compareTo(str_t1) : result;
            }
        });
        treeSet2.add("Derrick");
        treeSet2.add("Amy");
        treeSet2.add("Rose");
        treeSet2.add("Jam"); // 相同长度加不进去
        treeSet2.add("Timmy");
        treeSet2.add("Tom");// 相同长度加不进去


        System.out.println(treeSet2);


    }
}

TreeMap

package com.Map;

import org.junit.Test;

import java.util.Comparator;
import java.util.TreeMap;

/**
 * @author wty
 * @date 2022/10/10 12:33
 */
public class TreeMapExercise {
    
    
    @Test
    public void getTreeMap() {
    
    
        // 无参数,无序取出
        TreeMap treeMap = new TreeMap();
        treeMap.put("1", "Jack");
        treeMap.put("no2", "Tom");
        treeMap.put("李小璐", "PGONE");
        treeMap.put("smith", "史密斯");

        System.out.println(treeMap);

        // 按照key字符串首字母倒叙排序
        TreeMap treeMap2 = new TreeMap(new Comparator() {
    
    
            @Override
            public int compare(Object o1, Object o2) {
    
    
                return ((String) o2).compareTo((String) o1);
            }
        });
        System.out.println("按照key字符串首字母倒叙排序");
        treeMap2.put("1", "Jack");
        treeMap2.put("no2", "Tom");
        treeMap2.put("李小璐", "PGONE");
        treeMap2.put("smith", "史密斯");
        treeMap2.put("alice", "漫游记");
        System.out.println(treeMap2);

        // 按照key字符串长度排序,相同长度按首字母倒叙排序
        TreeMap treeMap3 = new TreeMap(new Comparator() {
    
    
            @Override
            public int compare(Object o1, Object o2) {
    
    
                String str_o1 = (String) o1;
                String str_o2 = (String) o2;

                int a = str_o1.length();
                int b = str_o2.length();

                int result = a == b ? str_o1.compareTo(str_o2) : a - b;

                return result;
            }
        });
        System.out.println("按照key字符串长度排序,相同长度按首字母顺叙排序");
        treeMap3.put("1", "Jack");
        treeMap3.put("no2", "Tom");
        treeMap3.put("李小璐", "PGONE");
        treeMap3.put("smith", "史密斯");
        treeMap3.put("alice", "漫游记");
        treeMap3.put("tonny", "理发师");
        System.out.println(treeMap3);
    }
}

Collections tool class

Collections tool class introduction
(1) Collections is a tool class for operating sets such as Set, List and Map
(2) Collections provides a series of static methods to sort, query and modify collection elements

Sorting operations (both static methods)

(1) reverse (List): reverse the order of elements in the List
(2) shuffle (List): Randomly sort the elements of the List collection
(3) sort (List): sort the elements of the specified List collection in ascending order according to the natural order of the elements Sorting
(4) sort (List, Comparator): sort the List collection according to the order generated by the specified Comparator
(5) swap (List, int, int): exchange the element at i and the element at j in the specified list collection

package com.CollectionsUse;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

/**
 * @author wty
 * @date 2022/10/10 14:57
 */
public class CollectionsUse {
    
    
    @Test
    public void getUse() {
    
    
        HashMap hashMap = new HashMap();
        hashMap.put("Jack", "Rose");
        hashMap.put("no.1", "Tony");
        hashMap.put("no.2", "Jancy");
        hashMap.put("This", "is my destney");

        /**
         * (1)reverse(List):反转List中元素的顺序
         * (2)shuffle(List):对List集合元素进行随机排序
         * (3)sort(List):根据元素的自然顺序对指定List集合元素按升序排序
         * (4)sort(List,Comparator):根据指定的Comparator产生的顺序对List集合进行排序
         * (5)swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
         */
        System.out.println(hashMap);


        ArrayList arrayList = new ArrayList();
        arrayList.add("Derrick");
        arrayList.add("Rose");
        arrayList.add("no.1");
        arrayList.add("2");
        arrayList.add("周润发");
        arrayList.add("周杰伦");
        arrayList.add("洪辰");
        System.out.println("----正常-----");
        System.out.println(arrayList);

        Collections.reverse(arrayList); // (1)reverse(List):反转List中元素的顺序
        System.out.println("----倒叙----");
        System.out.println(arrayList);

        System.out.println("----随机顺序----");
        Collections.shuffle(arrayList); // (2)shuffle(List):对List集合元素进行随机排序
        System.out.println(arrayList);


        System.out.println("----再次随机顺序----");
        Collections.shuffle(arrayList);
        System.out.println(arrayList);

        System.out.println("----自然排序----"); // 根据元素的自然顺序对指定List集合元素按升序排序
        Collections.sort(arrayList);
        System.out.println(arrayList);


        // sort(List,Comparator):根据指定的Comparator产生的顺序对List集合进行排序
        System.out.println("----自然排序Comparator:按照字符串长度大小排序----");
        Collections.sort(arrayList, new Comparator() {
    
    

            @Override
            public int compare(Object o1, Object o2) {
    
    

                if (o1 instanceof String && o2 instanceof String) {
    
    

                    String str_o1 = (String) o1;
                    String str_o2 = (String) o2;

                    int a = str_o1.length();
                    int b = str_o2.length();

                    int result = a == b ? str_o1.compareTo(str_o2) : a - b;
                    return result;
                } else {
    
    
                    return 0;
                }
            }
        });
        System.out.println(arrayList);

        // (5)swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
        System.out.println("----交换第一个和第三个元素----");
        Collections.swap(arrayList, 0, 2);
        System.out.println(arrayList);


    }
}

find and replace

(1) Object max(Collection): According to the natural order of the elements, returns the largest element in the given collection
(2) Object max(Collection, Comparator): returns the largest element in the given collection according to the order specified by Compartor
(3 )Object min(Collection)
(4)Object min(Collection, Object)
(5)int frequency(Collection, Object): returns the number of occurrences of the specified element in the specified collection
(6) void copy(List dest, List src): will The content in src is copied to dest
(7) boolean replaceAll(List list, Object oldVal, Object newVal): Replace all old values ​​of the List object with new values

@Test
    public void getUseCollections() {
    
    

        /**
         * (1)reverse(List):反转List中元素的顺序
         * (2)shuffle(List):对List集合元素进行随机排序
         * (3)sort(List):根据元素的自然顺序对指定List集合元素按升序排序
         * (4)sort(List,Comparator):根据指定的Comparator产生的顺序对List集合进行排序
         * (5)swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
         */


        ArrayList arrayList = new ArrayList();
        arrayList.add("Derrick");
        arrayList.add("Rose");
        arrayList.add("no.1");
        arrayList.add("2");
        arrayList.add("周润发");
        arrayList.add("周杰伦");
        arrayList.add("洪辰");
        arrayList.add("Rose");
        System.out.println("----正常-----");
        System.out.println(arrayList);

        /**
         * (1)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
         * (2)Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素
         * (3)Object min(Collection)
         * (4)Object min(Collection, Object)
         * (5)int frequency(Collection, Object):返回指定集合中指定元素的出现次数
         * (6)void copy(List dest, List src):将src中的内容复制到dest中
         * (7)boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值
         */

        // (1)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
        System.out.println("Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素");
        System.out.println(Collections.max(arrayList));

        // Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素
        System.out.println("Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素  ");
        System.out.println(Collections.max(arrayList, new Comparator() {
    
    
            @Override
            public int compare(Object o1, Object o2) {
    
    

                if (o1 instanceof String && o2 instanceof String) {
    
    

                    String str_o1 = (String) o1;
                    String str_o2 = (String) o2;

                    int a = str_o1.length();
                    int b = str_o2.length();

                    int result = a == b ? str_o1.compareTo(str_o2) : a - b;
                    return result;
                } else {
    
    
                    return 0;
                }
            }
        }));


        // (3)Object min(Collection):根据元素的自然顺序,返回给定集合中的最小元素
        System.out.println("Object min(Collection):根据元素的自然顺序,返回给定集合中的最小元素");
        System.out.println(Collections.min(arrayList));


        // Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素
        System.out.println("Object min(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最小元素  ");
        System.out.println(Collections.min(arrayList, new Comparator() {
    
    
            @Override
            public int compare(Object o1, Object o2) {
    
    

                if (o1 instanceof String && o2 instanceof String) {
    
    

                    String str_o1 = (String) o1;
                    String str_o2 = (String) o2;

                    int a = str_o1.length();
                    int b = str_o2.length();

                    int result = a == b ? str_o1.compareTo(str_o2) : a - b;
                    return result;
                } else {
    
    
                    return 0;
                }
            }
        }));

        // int frequency(Collection, Object):返回指定集合中指定元素的出现次数
        System.out.println("int frequency(Collection, Object):返回指定集合中指定元素的出现次数 ");
        System.out.println(Collections.frequency(arrayList, "Rose"));


        // void copy(List dest, List src):将src中的内容复制到dest中
        // 拷贝要注意 ,拷贝后的集合dest的元素个数要>=被拷贝集合arrayList
        // 一般情况在初始化dest指定大小和arrayList相同
        //ArrayList dest = new ArrayList(); // java.lang.IndexOutOfBoundsException
        ArrayList dest = new ArrayList();
        for (int i = 0; i < arrayList.size(); i++) {
    
    
            dest.add(i);
        }
        dest.add("Copy");
        dest.add("Paste");
        Collections.copy(dest, arrayList);
        System.out.println("dest集合元素:");
        System.out.println(dest);

        ArrayList arrayList1 = new ArrayList(10); // 指的是容量(达到后下次扩容成当前的1.5倍)
        System.out.println("arrayList1.size(): " + arrayList1.size());

        //boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值
        System.out.println("boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值  ");
        Collections.replaceAll(dest, "周润发", "金喜善"); // 如果有周润发就替换成金喜善
        System.out.println(dest);

    }

after class homework

Homework 1:

homework 1

package com.HomeWork;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * @author wty
 * @date 2022/10/10 16:06
 */
public class HomeWork01 {
    
    
    @Test
    public void HomeWork() {
    
    
        ArrayList arrayList = new ArrayList();
        arrayList.add(new News("新闻一:新冠确诊病例超过千万,数以万计印度教徒赶赴恒河"));
        arrayList.add(new News("新闻二:男子突然想起2个月前钓的鱼还在网兜"));
        System.out.println("----倒序遍历----");
        Collections.reverse(arrayList);
        for (Object o : arrayList) {
    
    
            // 先实例化对象
            News news = (News) o;

            if (news.getTitle().length() > 15) {
    
    
                System.out.println(news.getTitle().substring(0, 15) + "…………");
            } else {
    
    
                System.out.println(news.getTitle());
            }
        }
    }

    @Test
    public void HomeWork01_Teacher() {
    
    
        ArrayList arrayList = new ArrayList();
        arrayList.add(new News("新闻一:新冠确诊病例超过千万,数以万计印度教徒赶赴恒河"));
        arrayList.add(new News("新闻二:男子突然想起2个月前钓的鱼还在网兜"));
        System.out.println("----倒序遍历----");

        for (int i = arrayList.size() - 1; i >= 0; i--) {
    
    
            News news = (News) arrayList.get(i);
            System.out.println(substrTitle(news.getTitle()));
        }
    }

    public String substrTitle(String title) {
    
    
        if (null == title || "".equals(title)) {
    
    
            return "";
        }

        if (title.length() > 15) {
    
    
            return title.substring(0, 15) + "…………";
        } else {
    
    
            return title;
        }
    }
}

class News {
    
    
    private String title;
    private String text;

    public String getTitle() {
    
    
        return title;
    }

    public void setTitle(String title) {
    
    
        this.title = title;
    }

    public String getText() {
    
    
        return text;
    }

    public void setText(String text) {
    
    
        this.text = text;
    }

    @Override
    public String toString() {
    
    
        return "News{" +
                "title='" + title + '\'' +
                '}';
    }

    public News(String title) {
    
    
        this.title = title;
    }
}

Exercises after class 2

Exercises after class 2

package com.HomeWork;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author wty
 * @date 2022/10/10 16:38
 */
public class HomeWork02 {
    
    
    @Test
    public void getHomeWork02() {
    
    
        List list = new ArrayList();
        Car car1 = new Car("宝马", 400000);
        Car car2 = new Car("宾利", 5000000);
        Car car3 = new Car("劳斯莱斯", 60000000);
        Car car4 = new Car("法拉利", 70000000);
        list.add(car1);
        list.add(car2);
        System.out.println(list);

        list.remove(car1);
        System.out.println(list);

        System.out.println(list.contains(car2));

        System.out.println(list.size());
        System.out.println(list.isEmpty());
        list.clear();
        System.out.println(list);

        List list2 = new ArrayList();
        list2.add(car1);
        list2.add(car2);
        list2.add(car3);
        list2.add(car4);
        list.addAll(list2);
        System.out.println("----list.addAll(list2)----");
        System.out.println(list);


        System.out.println(list2.containsAll(list));
        list2.removeAll(list);
        System.out.println(list2);

        System.out.println("list增强for循环");

        for (Object o : list) {
    
    
            System.out.println(o);
        }

        System.out.println("list迭代器");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();
            System.out.println(next);
        }


    }
}

class Car {
    
    
    private String name;
    private double price;

    public Car(String name, double price) {
    
    
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
    
    
        return "Car{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

Exercises after class 3

Exercises after class 3

package com.HomeWork;

import org.junit.Test;

import java.util.*;

/**
 * @author wty
 * @date 2022/10/10 16:52
 */
public class HomeWork03 {
    
    
    @Test
    public void getHomeWork03() {
    
    
        Map map = new HashMap();
        map.put("1", new Worker("jack", 650));
        map.put("2", new Worker("tom", 1200));
        map.put("3", new Worker("smith", 2900));

        System.out.println("正常情况");
        Set set = map.keySet();
        for (Object o : set) {
    
    
            Worker worker = (Worker) map.get(o);
            System.out.println(worker);
        }

        // jack更改为2600元
        System.out.println("----更改工资和加薪后----");
        map.put("1", new Worker("jack", 2600));
        System.out.println(map);
        // 为所有员工加薪100元
        Set set1 = map.entrySet();
        Iterator iterator = set1.iterator();
        while (iterator.hasNext()) {
    
    
            Object next = iterator.next();

            Map.Entry entry = (Map.Entry) next;

            Worker worker = (Worker) entry.getValue();

            // 加薪
            worker.setSal(worker.getSal() + 100);
            //System.out.println(worker.getSal() + 100);

            System.out.println(worker);

        }

        System.out.println("----遍历工资----");
        // 把工资遍历出来
        Collection values = map.values();
        for (Object value : values) {
    
    
            Worker worker = (Worker) value;
            System.out.println(worker.getSal());
        }


    }
}

class Worker {
    
    
    private String name;
    private double sal;

    public Worker(String name, double sal) {
    
    
        this.name = name;
        this.sal = sal;
    }

    @Override
    public String toString() {
    
    
        return name + "————" + sal + "元";
    }

    public double getSal() {
    
    
        return sal;
    }

    public void setSal(double sal) {
    
    
        this.sal = sal;
    }
}

short answer questions

Try to analyze how HashSet and TreeSet achieve deduplication

(1) The deduplication mechanism of HashSet: hashCode() + equals(). The bottom layer first saves the object, performs calculations to obtain a hash value, and obtains the corresponding index through the hash value. If there is no data at the location of the table index, Just store it directly, if there is data, perform equals comparison [traversal comparison], if the comparison is not the same, add it, otherwise don't add it.
(2) TreeSet's deduplication mechanism: If you pass in a Comparator anonymous object, use the implemented compare to deduplicate. If the method returns 0, it will be considered the same element/data and will not be added. If you do not pass in For a Comparator anonymous object, use the compareTo of the Comparator interface implemented by the object you added to deduplicate.

Homework 5:

package com.HomeWork;

import org.junit.Test;

import java.util.TreeMap;
import java.util.TreeSet;

/**
 * @author wty
 * @date 2022/10/10 17:47
 */
public class HomeWork05 {
    
    
    @Test
    public void getHomeWorker05() {
    
    
        TreeSet treeSet = new TreeSet();
        treeSet.add(new Person()); // java.lang.ClassCastException 报错
        // 错误原因:treeSet在add时候会执行
        /**
         *     final int compare(Object var1, Object var2) {
         *         return this.comparator == null ? ((Comparable)var1).compareTo(var2) : this.comparator.compare(var1, var2);
         *     }
         *
         *     会把加入的元素var1 转换成(Comparable) 对象,所以Person必须实现Comparable接口才行
         */
    }
}

class Person implements Comparable {
    
     // 实现之后再添加就不会报错了
    /**
     *TreeSet的去重机制:如果你传入了一个Comparator匿名对象,就使用实现的compare去重,如果方法返回  	0,就认为是相同的元素/数据,就不添加,如果你没有传入一个Comparator匿名对象,则以你添加的对象实现的Comparator接口的compareTo去重。
     *     final int compare(Object var1, Object var2) {
     *         return this.comparator == null ? ((Comparable)var1).compareTo(var2) : this.comparator.compare(var1, var2);
     *     }
     * @param o
     * @return
     */
    @Override
    public int compareTo(Object o) {
    
    
        return 0;
    }
}

Homework 7

Comparison of Vector and ArrayList

           底层结构      版本   线程安全(同步)效率    扩容倍数
ArrayList  可变数组      1.2    线程不安全,效率高   无参第一次扩容至10,从第二次开始按照1.5倍扩容

Vector     可变数组      1.0    线程安全,效率低     无参第一次扩容至10,从第二次开始按照2倍扩容
name underlying structure Version thread safety (synchronization) efficiency Expansion multiple
ArrayList mutable array 1.2 thread unsafe high No parameter expansion to 10 for the first time, and 1.5 times expansion from the second time
Vector mutable array 1.0 thread safety Low No parameter expansion to 10 for the first time, and 2 times expansion from the second time

collection summary

Finally, I sorted out all the collections in this chapter and integrated an excel file, which you can download by yourself if you need it. Of course, you can also organize according to your own understanding, here is for reference only.
Collection excel organizes all collections in this chapter

Guess you like

Origin blog.csdn.net/sinat_38316216/article/details/127388493