Set Mastery (Set + Map)

Posted by hughmill on Tue, 08 Feb 2022 04:00:59 +0100

Collective Mastery

Set set:

Differences between HashSet set and TreeSet set:

HashSet: the bottom layer is the hash table, and the thread is not safe

TreeSet: the bottom layer is a binary tree, and the thread is not safe

Hash table:

Introduction: the two implementation classes of Set set are HashSet and LinkedHashSet. The underlying implementation is hash table

1.Hash is generally translated into hash, and some are directly translated into hash. It is designed from the perspective of fast access. It is also a typical practice of space for time. As the name suggests, the data structure can be understood as a linear table, but the elements in it are not closely arranged, but there may be gaps

2. Hash Table: it is a data structure directly accessed according to the key value, that is, it accesses records by mapping the key value to a position in the table to speed up the search. This mapping function is called Hash Table

3. The composition of hash table is: array + linked list. According to what rules are these elements stored in the array? Generally, it is obtained through hash (key)% length, that is, the hash value of the element's key is obtained by modeling the array length

Understanding of hash table expansion:

However, when the hash table is nearly full, the performance is low due to the expansion of the array (transfer to a larger hash table)

The default hash cell size of Java is all powers of 2, and the initial value is 16 (2 ^ 4). If 75% of the 16 linked lists have data, it is considered that the loading factor reaches the default 0.75. hashSet began to favor hash, that is, abandon all the original hash structure, recalculate the storage location of each data, and so on

Load factor: 0.75 - > > the space provided by the hash table is 16, that is, the capacity will be expanded when it reaches 12

Implementation of weight removal mechanism:

If we have a data (hash code 76268) and the HashSet has 128 hash units at this time, it is possible to insert this data into the 108th and linked list of the array (76268% 128 = 108). But this is only possible. If an old data and a new data equal() = true are found in the linked list No. 108, the new data will be deemed to have been added and will not be repeatedly dropped into the linked list

advantage:

hash table insertion and lookup are excellent

For search: after calculating the remainder directly according to the hash code of the data and the array size of the hash table, you can get the position of the array, and then find out whether there is this data in the linked list. Because the search speed of the array itself is fast, the search efficiency is reflected in the linked list, but in reality, there are few data in a linked list, some or even none, Therefore, there is almost no cost of iteration, so the search efficiency of the hash table is based on the number of data in the linked list pointed to by the hash unit

For insertion: the insertion speed of the array is slow, while the insertion speed of the linked list is fast. When we no longer use the hash table, we don't need to change the structure of the array. We just need to enter the corresponding linked list and operate the linked list after finding the corresponding array subscript. Therefore, the overall insertion sequence of the hash table is also fast

Binary tree:

Concept: a tree is composed of root nodes and several sub trees. A tree consists of a set and a relationship defined on the set. The elements in the collection are called the nodes of the tree, and the defined relationship is called parent-child relationship. The parent-child relationship establishes a hierarchical structure between the nodes of the tree. In this hierarchy, a node has a special status. This node is called the root node of the tree, or the root of the tree.

Note: the number of child nodes of each node of an ordinary tree is not necessarily 2

Note: a single node is also a tree, and the root of the tree is the node itself

Note: an empty set is also a tree, which is called an empty tree. There are no nodes in the empty tree

forest:

Related concepts:

A collection of M (m ≥ 0) disjoint trees is called a forest

Child node or child node: the child node of the subtree contained in a node is called the child node of the node

Degree of node: the number of child nodes in a node is called the degree of the node

Leaf node or terminal node: a node with a degree of 0 is called a leaf node

Non terminal node or branch node: a node whose degree is not 0

Parent node or parent node: if a node contains child nodes, this node is called the parent node of its child nodes

Sibling node: a node with the same parent node is called a sibling node

Tree degree: the degree of the largest node in a tree is called the degree of the tree

Node hierarchy: defined from the root. The root is the first layer, and the following child nodes are the second layer, and so on

Height and depth of tree: the maximum level of nodes in the tree

Cousin node: nodes with parents on the same level are cousins to each other

Ancestor of a node: all nodes on the branch from the following node to the node

Descendant: any node in the subtree with a node as the root is called the descendant of the node

Tree classification:

Unordered tree: there is no sequential relationship between the child nodes of any node in the tree. This kind of tree is called unordered tree, also known as free tree

Ordered tree: there is a sequential relationship between the child nodes of any node in the tree. This kind of tree is called ordered tree

Binary tree: a tree with at most two subtrees per node is called a binary tree

Full binary tree: a tree in which all nodes except leaf nodes contain two subtrees is called a full binary tree

Complete binary tree: a full binary tree with 2^k-1 nodes is called a complete binary tree

Huffman tree (optimal binary tree): the binary tree with the shortest weighted path strength is called Huffman tree or optimal binary tree

Traversal of binary tree

1. Binary tree is a very important data structure. It has the characteristics of array and linked list at the same time: it can find as quickly as array or add as quickly as linked list. But he also has his own shortcomings: the deletion operation is complex

2. Binary tree: an ordered tree with at most two subtrees per node. When using a binary tree, the data is not inserted into the node casually. The key value of the left child node of a node must be less than this node, and the key value of the right child node must be greater than or equal to this node. Therefore, it is also called binary search tree, binary sort tree and binary search tree

Traversal method of binary tree:

Preorder traversal:

First visit the root, then traverse the left subtree first, and finally traverse the right subtree first (around the root)

Middle order traversal:

First, traverse the left subtree in middle order, then visit the root, and finally traverse the right subtree in middle order (left and right)

Post order traversal:

First, the post order traverses the left subtree, then the post order traverses the right subtree, and finally accesses the root

Principle of weight removal:

HashSet and LinkedHashSet

This is achieved by calling the hashCode and equals methods of the element. First, call the hashCode method to get the hash code value of the current object and compare the hash code values of the two objects. If they are different, they are directly regarded as two objects and no longer call equals. If they are the same, continue to call the equals method and return true, which is regarded as an object, If false is returned, it is considered to be two objects

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-bz4y5oJZ-1622422018276)(C:\Users326\Desktop\dayHomework \ data structure \ QQ screenshot 20210530151636.png)]

package bk.javase;

import java.util.HashSet;
import java.util.StringJoiner;

public class p530 {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("java");
        set.add("php");
        set.add("bigData");
        set.add("java");
        System.out.println(set); //[bigData, java, php]
        //Note that the add method of Set itself implements the de duplication function internally. By default, it calls the hashCode method and equals method of the element
        //The String method has overridden the hashCode and equals methods by default

        //Create a HashSet in
        HashSet<Person> set2 = new HashSet<>();
        set2.add(new Person("zhangsan", 20));
        set2.add(new Person("lisi", 30));
        set2.add(new Person("wangwu", 40));
        set2.add(new Person("zhangsan", 20));
        System.out.println(set2);
        //[Person[name='wangwu', age=40], Person[name='lisi', age=30], Person[name='zhangsan', age=20], Person[name='zhangsan', age=20]]
        //The addresses of the four objects from new must be different, so the first step in HashSet is to judge directly, which is different.
        //Solution:
        //Make their own comparison rules: compare them according to age and gender. If they are the same, they are considered to be the same person
        //Step 1: Rewrite hashcode method
        //Step 2: rewrite the equals method
//[Person[name='lisi', age=30], Person[name='zhangsan', age=20], Person[name='wangwu', age=40]]
    }
}

class Person{
    String name;
    int age;

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

    @Override
    public String toString() {
        return new StringJoiner(", ", Person.class.getSimpleName() + "[", "]")
                .add("name='" + name + "'")
                .add("age=" + age)
                .toString();
    }

    //Specify the comparison rules by yourself: compare them according to age and name. If they are the same, they are considered to be the same person
    @Override
    public boolean equals(Object obj) {
       //If the two addresses are the same, the content must be the same
        if (this == obj) return true;
        //If obj is empty, the content must be different
        if (obj == null) return false;
        //If the real types of the two are different, the content must be different
        if(this.getClass() != obj.getClass()) return false;
        //Strong conversion to subclass real type
        Person p = (Person) obj;
        //Start comparison
        if (age == p.age && name.equals(p.name)){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public int hashCode() {
        return name.hashCode() + age * 1000;
    }
}
TreeSet

Introduction: TreeSet is the implementation class of the Set interface. The bottom layer is a binary tree. Such a Set will remove the duplicate of the elements added to the Set. At the same time, the elements added to the Set will be automatically sorted in ascending order

Comparable interface (default sort)

If a class implements this interface, it means that it implements a rule that can size with its own object. At this time, the objects of this class can be directly stored in the TreeSet collection. Therefore, the TreeSet collection at this time already knows how to compare the sizes of the objects of the two classes

package bk.javase.p530;

import java.util.StringJoiner;
import java.util.TreeSet;

public class TreeSetTest {
    public static void main(String[] args){
        //Store string in TreeSet
    /*
    TreeSet The add method implements sorting and de duplication by calling the compareTo method of the element
    String Class has implemented the Comparable interface and overridden the compareTo method
     */
        TreeSet<String> set = new TreeSet<>();
        set.add("java");
        set.add("php");
        set.add("bigData");
        set.add("java");
        System.out.println(set);
        //[bigData, java, php]

        //Create a new TreeSet collection
        TreeSet<Person2> set2 = new TreeSet<>();
        set2.add(new Person2("zhangsan",20));
        set2.add(new Person2("lisi",30));
        set2.add(new Person2("zhangsan",20));
        System.out.println(set2);
//Exception in thread "main" java.lang.ClassCastException: bk.javase.p530.Person2 cannot be cast to java.lang.Comparable
        //TreeSet is also an element that cannot be repeated, but its implementation is different from HashSet. Its de duplication is implemented according to the compareTo method in the Comparable interface
        //[Person2[name='zhangsan', age=20], Person2[name='lisi', age=30]]
    }
}

class Person2 implements Comparable<Person2>{
    String name;
    int age;

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

    @Override
    public String toString() {
        return new StringJoiner(", ", Person2.class.getSimpleName() + "[", "]")
                .add("name='" + name + "'")
                .add("age=" + age)
                .toString();
    }

//Make your own comparison rules: compare your name first and then your age
    /*
    == 0   this == o
    >0 | < 0 this != o
     */
    @Override
    public int compareTo(Person2 person2) {
        if (person2.name.equals(name) && person2.age == age){
            return 0;
        }
        return 1;
    }
}

Comparable interface:

Definition: a comparator object that implements the compare () method of the Comparable interface is used for comparison

Question 1: why is there a comparator when there is a Comparable interface?

Answer:

1. For custom classes, the code is written by ourselves. We can make our own sorting rules whether through Comparator or Comparable, so there is no big difference between the final method,

2. It has a great impact on the system class. The code in the system can only be used and cannot be modified, which means that the comparison rules implemented through Comparable in the system have been determined. This is the other rules we want to use to compare the current system class objects. We can only use Comparator to re formulate the comparison rules

Question 2: what is the priority of manual sorting and default sorting?

A: the priority of manual sorting is higher than the default sorting. We can let TreeSet obtain the comparison methods of Comparable and Comparator at the same time. At this time, for the system class, the default sorting is the system's own, and the manual sorting rules implemented through the Comparator are what we want. Therefore, the system class must give manual sorting priority to the default sorting in order to use the post color sorting rules normally

package bk.javase.p530;
import java.util.Comparator;
import java.util.StringJoiner;
import java.util.TreeSet;

public class TestMyCom {
    public static void main(String[] args){
        //Make their own comparison rules and compare them according to age and gender. If they are the same, they are considered to be the same person
        //2. Apply the comparator to TreeSet
        ComWithPerson com = new ComWithPerson();
        TreeSet<Person4> set = new TreeSet<>(com);
        set.add(new Person4("zhangsan",20));
        set.add(new Person4("lisi",30));
        set.add(new Person4("zhangsan",20));
        System.out.println(set);
        /*
        I'm Comparator
        [Person4[name='lisi', age=30], Person4[name='zhangsan', age=20]]
        If Comparator and Comparable are implemented at the same time, the priority of Comparator is higher than that of Comparable
         */
    }
}
//1. Generate a Comparator (an object that implements the class in the Comparator interface)
class ComWithPerson implements Comparator<Person4>{

    @Override
    public int compare(Person4 o1, Person4 o2) {
        int num = o1.name.compareTo(o2.name);
        System.out.println("I am Comparator");
        return num == 0 ? o1.age - o2.age : num;
    }

}

//Direct implementation of Comparable interface
class Person4 implements Comparable<Person4>{
    String name;
    int age;

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

    @Override
    public String toString() {
        return new StringJoiner(", ", Person4.class.getSimpleName() + "[", "]")
                .add("name='" + name + "'")
                .add("age=" + age)
                .toString();
    }

    //Make your own comparison rules: if the name and age are the same, it is considered to be the same person
    @Override
    public int compareTo(Person4 o) {
        //Compare names first and then ages
        int num = o.name.compareTo(name);
        System.out.println("I am Comparable");
        return num == 0 ? age - o.age : num;
    }
}

Usage scenarios of Comparable and Comparator

1. In most cases, this object adopts the same size comparison method in the project. For example, in most cases, the size of a Person class is compared according to age. At this time, the Person class can implement the Comparable interface

2. If an object of a class uses different rules from the default when temporarily comparing the size, for example, a Person class, in most cases, uses age for size comparison, but temporarily needs to use height for comparison. At this time, you can use Comparator to temporarily complete the comparison. Moreover, Comparator takes precedence over Comparable

3. If the system class wants to implement new comparison rules, use Comparator

De duplication of TreeSet:

Whether Comparator or Comparable is used, if the result of size comparison between two objects is 0, the two objects are the same object, and the weight removal will be completed in TreeSet

Note: the de duplication of elements in TreeSet is only related to the size comparison results of objects, and has nothing to do with hashCode(), equals()

Map collection

Map API

Return valuemethoddescribe
Vput(K key,V value)Insert, repeat and overwrite
VputlfAbsent(K key,V value)Insert, repeat, do not overwrite
voidputAll(Map<K,V> ,map)Adds all key value pairs in the parameter Map collection to the current collection
Vremove(Object key)Delete k-v through key and return v
booleanremove(Object key,Object value)Delete by k-v
voidclear()empty
Vreplace(K k,V v)Modify k-v and return to the original v
booleanreplaceAll(K k,V old,V new)Match k-v successfully, change to v
Vget(K k)Gets the specified V
VgetOrDefault(K k)Gets the specified v, and returns the default value if it is not found
intsize()Gets the number of elements in the collection
booleanisEmpty()Judge whether the set is empty
booleanconstainsKey(K k)Determines whether the specified key is included
booleanconstainsValue(V v)Determines whether the specified value is included
SetkeySet()Gets a collection of all keys
Collectionvalues()Gets a collection of all values
package bk.javase.p530;

import java.util.*;

public class TestMap {
    public static void main(String[] args){
        //1. Instantiate an implementation class object of a Map collection and transform it upward into an interface type
        Map<String,String> map = new HashMap<>();

        //2. Insert data into the set
        String value = map.put("name","xiaoming");
        System.out.println(value); //Since this key value pair is added for the first time, there is no overwritten value in the collection, so the return value is null

        String value2 = map.put("name","xiaohong");
        System.out.println(value2);//This is the second time to set the value of name, which will be overwritten with xiaohong to xiaoming, so xiaoming is returned

        //3. Insert data into the set:
        String value3 = map.putIfAbsent("name","xiaohong");
        System.out.println(value3);//The values returned here are those that already exist in the collection. Because they already exist, they will not be added

        //4. Add all key value pairs in a Map set to the current set
        Map<String,String> temp = new HashMap<>();
        temp.put("height","175");
        temp.put("weight", "65");
        temp.put("age","30");
        map.putAll(temp);

        //5. Delete: delete a key value pair through the key and return the value in the deleted key value pair
        String value4 = map.remove("weight");
        System.out.println(value4);

        //6. Delete
        boolean value5 = map.remove("age","30");
        System.out.println(value5);

        //7. Empty the collection
//        map.clear();

        //8. Modify a key value pair in the set (through key and value modification)
        String value6 = map.replace("name","xiaohei");
        System.out.println(value6); //Returns the overwritten value
        String value7 = map.replace("age","30");
        System.out.println(value7);//Since there is no age in the map, this returns null

        //9. Modify: only when the key and oldValue match, it will be modified to newValue
        boolean value8 = map.replace("name","xiaohei","xiaohong");
        System.out.println(value8);

        //10. Get the value through the key
        String value9 = map.get("name1");
        System.out.println(value9);

        //11. Get the value through the key. If the key does not exist, the default value will be returned
        String value10 = map.getOrDefault("name1","aaa");//aaa
        System.out.println(value10);

        //12. Determine whether a key is included
        boolean value11 = map.containsValue("175");
        System.out.println(value11);
        boolean value12 = map.containsKey("height");
        System.out.println(value12);

        //13. Get the Set set composed of all keys
        Set<String> keys = map.keySet();
        //14. Get the Collection set composed of all values
        Collection<String> values = map.values();
        System.out.println(map);

    }
}

Traversal of Map collection:

1. Use keySet() to traverse

//1. Get the set that stores all the keys
Set<String> keys = map.keySet();
//2. Use the key to traverse
for(String key : keys){
    System.out.println("key = "+ key + "value = " + map.get(key));
}

2. Use the forEach method

This forEach method is not a method in the Iterable interface, but a method defined in the Map. In terms of function, it is similar to the method in Iterable, but only different in the parameter part

private static void forEach(Map<String,String> map){
	map.forEach(k,v)->{
        //k: Every key traversed
        //v: Each value traversed
        System.out.println("key = "+ k + ",value = " + v);   
    }
}

3. Use EntrySet to traverse

Entry<K,V>:

It is the internal static interface in Map. An Entry object, which we call an entity, is used to describe each key value pair in the collection

package bk.javase.p530;

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

public class TestKeySet {
    public static void main(String[] args){
        Map<String,String> map = new HashMap<String, String>();
        //1. Get a Set set that stores all entries
        Set<Map.Entry<String,String>> entries = map.entrySet();
        //2. Traverse Set
        for (Map.Entry<String,String> entry : entries){
            //2.1 get key
            String key = entry.getKey();
            //2.2 get value
            String value = entry.getValue();
            //2.3 display results
            System.out.println("key = " + key + ",value = " + value);
            
             /*
        You can modify the value of the original map through setValue
        Mapping item (key value pair). Map. The entryset side returns the mapped Collection view, where the elements belong to this class
        The only way to get the mapping item reference is through the iterator of this collection view. These maps The entry object is only available in
        Effective during iterations. More formally, if the underlying mapping is modified after the iterator returns the item, the behavior of some mapping items is uncertain
        In addition to performing operations on mapped items through setValue
         */
            entry.setValue("hello");
        }
    }
}

HashMap

Basic implementation of HashMap:

Note: HashMap can realize sorting. Because its underlying data structure is realized by array + linked list + binary tree, it can realize sorting. At the same time, the purpose of this is to improve the efficiency of data storage

Differences between HashMap and HashTable:

1.HashMap is a thread unsafe collection, and HashTable is a thread safe collection

2. The null key value allowed in HashMap is not allowed in HashTable

3. The parent class of HashMap is AbstractMap, and the parent class of HashTable is Dictionary

4. For the new implementation class of the Map interface of HashMap, the efficiency of the underlying algorithm is better than that of HashTable

TreeMap

Principle realization:

Like TreeSet, it is arranged, but TreeMap is implemented according to the size of the key. For values, we can understand the values in TreeSet as the keys in TreeMap

be careful:

1. What data types can be used as key s?

The compareTo() method in the Comparable interface is implemented

The compare() method in the Comparator interface is implemented

2. Who often acts as a key?

Custom wrapper, class (String)

3. Representatives who cannot

ArrayList, array, LinkedList (if the comparator built for them can also be compared, but it is not recommended)

4. Whether an element can be used as a key has nothing to do with the internal members of the element

LinkedHashMap:

Similar to HashMap, the bottom layer maintains a linked list to record the storage order of each key, that is, in LinkedHashMap, the addition order of key value pairs can be guaranteed, similar to LinkedHashSet and HashSet

ashTable is not allowed

3. The parent class of HashMap is AbstractMap, and the parent class of HashTable is Dictionary

4. For the new implementation class of the Map interface of HashMap, the efficiency of the underlying algorithm is better than that of HashTable

TreeMap

Principle realization:

Like TreeSet, it is arranged, but TreeMap is implemented according to the size of the key. For values, we can understand the values in TreeSet as the keys in TreeMap

be careful:

1. What data types can be used as key s?

The compareTo() method in the Comparable interface is implemented

The compare() method in the Comparator interface is implemented

2. Who often acts as a key?

String, wrapper class, custom class (interface implemented)

3. Representatives who cannot

ArrayList, array, LinkedList (if the comparator built for them can also be compared, but it is not recommended)

4. Whether an element can be used as a key has nothing to do with the internal members of the element

LinkedHashMap:

Similar to HashMap, the bottom layer maintains a linked list to record the storage order of each key, that is, in LinkedHashMap, the addition order of key value pairs can be guaranteed, similar to LinkedHashSet and HashSet