Improve Java development efficiency: Master the common methods and basic principles of HashMap


foreword

In order to consolidate the knowledge learned, the author tried to start publishing some blogs of learning notes for future review. Of course, it would be great if it could help some newcomers learn new technologies. The author is a piece of food. If there are any mistakes in the records in the article, readers and friends are welcome to criticize and correct.
(The reference source code of the blog can be found in the resources on my homepage. If you have any questions during the learning process, please feel free to ask me in the comment area)

I. Overview

1. Know HashMap

  • HashMap is a hash table that stores key-value pairs (key-value) mapping

  • HashMap implements the Map interface, stores data according to the HashCode value of the key , has a fast access speed, allows at most one record key to be null, and does not support thread synchronization

  • HashMap is unordered , that is, the order of insertion is not recorded

  • HashMap inherits from AbstractMap and implements Map , Cloneable , and java.io.Serializable interfaces

insert image description here

  • The key and value types of HashMap can be the same or different. They can be string (String) type key and value, or integer (Integer) key and string (String) type value

2. The role and importance of HashMap

HashMap is one of the most commonly used data structures in Java. It implements the Map interface and provides key-value pair storage and retrieval functions. The role and importance of HashMap are reflected in the following aspects:

  • Storage and retrieval : HashMap can store a large amount of key-value pair data and quickly retrieve the corresponding value through the key. It uses a hash algorithm to map keys to array positions, enabling efficient lookup operations. This allows HashMap to quickly insert, retrieve and delete elements when processing large amounts of data .
  • Efficient performance : Since the internal implementation of HashMap utilizes the hash algorithm, the average time complexity of its search operation is O(1) (constant time). This means that HashMap can perform insertion and lookup operations in a very efficient manner in most cases, making it ideal for handling large-scale data.
  • Flexibility : The keys and values ​​in HashMap can be any type of object. This allows us to store different types of data in HashMap according to specific needs, without being limited to specific data types .
  • Unique key : HashMap requires the uniqueness of the key, which means that each key can only appear once in the HashMap . This is very useful for scenarios where the key is used to find the value. For example, when storing user information, the user ID can be used as the key to quickly retrieve the user's information.
  • Scalability : HashMap can be dynamically expanded, automatically adjusting capacity according to the growth of stored data , thus avoiding the cumbersome operations of manual capacity management.

3. Briefly explain the basic principle and implementation of HashMap

When using HashMap to store data, it will map key-value pairs into an internal array according to the hash value of the key . The basic principle can be summarized in the following steps:

1. HashMap function

  • Hash function : The elements in the hash table are determined by the hash function . The keyword Key of the data element is used as an argument , and the value calculated through a certain functional relationship (called a hash function) is the element storage address . The design of the hash function in the hash table is very important, which is also one of the key issues in the process of building the hash table

  • Hash function calculation : When we insert a key-value pair into HashMap, HashMap will call the hashCode() method of the key to calculate its hash value . The hash value is an integer used to map the key to the index position of the array

  • Hash value conversion : In order to ensure that the hash value is suitable as an index of the array , HashMap will perform some conversion operations on the calculated hash value. A common conversion method is to use the hash value and the length of the array to perform a modulo operation to obtain an index value within the range of the array

insert image description here

2. HashMap storage

  • Array storage : HashMap maintains an array internally , and each array element corresponds to a bucket . Each bucket can store one or more key-value pairs . When inserting or searching for elements, HashMap finds the corresponding bucket according to the calculated index value , and then performs corresponding operations in the bucket

  • Dynamic expansion : In order to improve the performance of HashMap, after the number of stored key-value pairs reaches a certain threshold, HashMap will automatically expand its capacity. The scaling process involves recalculating key hashes and redistributing key-value pairs into larger arrays . This reduces hash collisions and improves operational efficiency

insert image description here

3. HashMap conflict handling

  • Collision handling : Since different keys may have the same hash value, this leads to collisions. When a conflict occurs , HashMap uses a data structure such as a linked list or a red-black tree to store key-value pairs with the same hash value . These data structures allow storing multiple key-value pairs in conflicting locations and distinguishing them by comparing the keys' equals() method

  • Linked list : Before JDK 8 , HashMap used a linked list to resolve conflicts. When multiple key-value pairs are mapped to the same bucket, they form a linked list. Find, insert, or delete key-value pairs by traversing the linked list . However, when the length of the linked list is too long, it will affect the performance of HashMap

  • Red-black tree : Starting from JDK 8 , when the length of the linked list exceeds a threshold (8 by default), the linked list will be automatically converted into a red-black tree to improve operation efficiency. The search, insertion, and deletion operations of red-black trees have low time complexity and can maintain logarithmic time complexity in the average case

insert image description here

  • Entry object : HashMap uses Entry objects to represent key-value pairs . Each Entry object contains a key, a value, and a reference to the next Entry (forming a linked list or a red-black tree structure) . Before JDK 8, each Entry object also contained a reference to the previous Entry to support fast deletion operations

In general, HashMap calculates the hash value of the key through the hash function, and maps the key-value pairs to the buckets in the internal array. Use data structures such as linked lists or red-black trees to solve hash conflicts, and improve performance through dynamic expansion. This implementation enables HashMap to perform insertion, lookup, and deletion operations in constant time complexity.

2. Understand the creation of HashMap and its common operation methods

1. The creation of HashMap

1. About the packaging class
The elements in HashMap are actually objects. Some common basic types can use its packaging classes. The corresponding packaging classes for basic types are as follows:

basic type reference type
boolean Boolean
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character

2. HashMap should use wrapper type instead of basic type

  • Generic Restrictions : HashMap is a generic class that can store keys and values ​​of any type. However, generic type parameters can only be classes and not primitive types . Therefore, if you want to store primitive types as keys or values ​​in HashMap, you need to wrap them into corresponding wrapper types, such as Integer, Double, Boolean, etc.

  • Null value handling : the basic type is not allowed to be null, but the wrapping type can be null . In HashMap, both key and value can be null. For basic types, when we need to store a null value in HashMap, we must use the corresponding wrapper type.

3. Example of creating HashMap

  • The HashMap class is located in the java.util package and needs to be introduced before use. The syntax is as follows:
import java.util.HashMap; // 引入 HashMap 类
  • In the following example, we create a HashMap object Sites, an integer (Integer) key and a string (String) type value:
HashMap<Integer, String> Sites = new HashMap<Integer, String>();

2. Add element put()

  • To add elements to HashMap, you can use put() method. The put() method accepts two parameters, the first parameter is the key (Key) , and the second parameter is the value (Value) . Following is an example of adding elements to HashMap:
  map.put("A", 1);
  map.put("B", 2);
  map.put("C", 3);
  • It should be noted that HashMap allows null as key and value. If you try to add null as key to HashMap, it will only have one key value pair with null key. In addition, because HashMap is not thread-safe, if you use HashMap in a multi-threaded environment, please consider using thread-safe ConcurrentHashMap .

3. Access element get()

  • To access elements in HashMap, you can use get() method. The get() method takes one parameter , the key to get (Key) , and returns the value associated with that key (Value)
  int value1 = map.get("A"); // 访问键为"A"的值
  int value2 = map.get("B"); // 访问键为"B"的值
  • It should be noted that if the specified key does not exist in the HashMap, the get() method will return null . Therefore, before using the get() method to get the value, it is better to use the containsKey() method to check whether the specified key exists in the HashMap

  • In addition, HashMap also provides other methods to access elements, such as the keySet() method can return a collection of all keys , the values() method can return a collection of all values , and the entrySet() method can return a collection containing key-value pairs . By using these methods, you can iterate over all key-value pairs in the HashMap and perform corresponding operations

4. Delete element remove()

  • Use the remove(Object key) method: This method accepts a key as a parameter and deletes the corresponding key-value pair from the HashMap. For example, if you want to delete the element with key "key1", you can use the following code:
  HashMap<String, String> hashMap = new HashMap<>();
  hashMap.remove("key1");
  • Use iterator to traverse and delete elements: You can use Iterator to traverse the key-value pairs of HashMap , and use the remove() method to delete elements. This approach is suitable for cases where elements need to be removed conditionally. For example, if you want to delete all key-value pairs with value "value1", you can use the following code:
HashMap<String, String> hashMap = new HashMap<>();
Iterator<Map.Entry<String, String>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
    
    
    Map.Entry<String, String> entry = iterator.next();
    if (entry.getValue().equals("value1")) {
    
    
        iterator.remove();
    }
}
  • To delete all key-value pairs (key-value), you can use the clear method:
 hashMap.clear();

5. Calculate size size()

  • To calculate the size of the HashMap (ie the number of key-value pairs), you can use the size() method. This method returns the number of key-value pairs in the HashMap.
  • The following is a sample code for calculating the size of a HashMap using the size() method:
  int size = hashMap.size();

6. Iterate HashMap for-each

  • You can use for-each to iterate elements in HashMap

  • If you only want to get the key, you can use the keySet() method , and then you can get the corresponding value through get(key), if you only want to get the value, you can use the values() method

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    
    
    public static void main(String[] args) {
    
    
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        // 输出 key 和 value
        for (Integer i : Sites.keySet()) {
    
    
            System.out.println("key: " + i + " value: " + Sites.get(i));
        }
        // 返回所有 value 值
        for(String value: Sites.values()) {
    
    
          // 输出每一个value
          System.out.print(value + ", ");
        }
    }
}
  • Execute the above code, the output is as follows:

key: 1 value: Google
key: 2 value: Runoob
key: 3 value: Taobao
key: 4 value: Zhihu
Google, Runoob, Taobao, Zhihu,

7. Determine whether it is empty isEmpty()

  • To determine whether the HashMap is empty, you can use the isEmpty() method. This method will return a boolean value indicating whether the HashMap is empty

  • The following is a sample code that uses the isEmpty() method to determine whether the HashMap is empty:

 System.out.println("Is HashMap empty? " + hashMap.isEmpty()

8. Determine whether the specified key exists in the HashMap containsKey()

  • To determine whether a HashMap contains a particular key (key), you can use the containsKey(Object key) method. This method accepts a key as a parameter and returns a boolean indicating whether the HashMap contains the key

  • The following is a sample code for using the containsKey(Object key) method to determine whether a HashMap contains a key:

System.out.println("Does HashMap contain key 'key2'? " + hashMap.containsKey("key1"));

9. Obtain the corresponding value of the specified key, if the key cannot be found, return the default value set by getOrDefault()

  • The getOrDefault() method obtains the corresponding value of the specified key, if the key cannot be found, it returns the default value set

  • The syntax of the getOrDefault() method is:

hashmap.getOrDefault(Object key, V defaultValue)

  • Parameter Description:

1. key - key
2. defaultValue - when the specified key does not exist in the mapping relationship, the default value returned

  • Return value: Returns the value mapped to the key, if the given key cannot be found in the mapping relationship, returns the specified default value
import java.util.HashMap;

class Main {
    
    
    public static void main(String[] args) {
    
    
        // 创建一个 HashMap
        HashMap<Integer, String> sites = new HashMap<>();

        // 往 HashMap 添加一些元素
        sites.put(1, "Google");
        sites.put(2, "Runoob");
        sites.put(3, "Taobao");
        System.out.println("sites HashMap: " + sites);

        // key 的映射存在于 HashMap 中
        // Not Found - 如果 HashMap 中没有该 key,则返回默认值
        String value1 = sites.getOrDefault(1, "Not Found");
        System.out.println("Value for key 1:  " + value1);

        // key 的映射不存在于 HashMap 中
        // Not Found - 如果 HashMap 中没有该 key,则返回默认值
        String value2 = sites.getOrDefault(4, "Not Found");
        System.out.println("Value for key 4: " + value2);
    }
}
  • The output of executing the above program is:

Value for key 1: Google
Value for key 4: Not Found

Summarize

Everyone is welcome to leave a message for exchange and criticism. If the article is helpful to you or you think the author's writing is not bad, you can click to follow, like, and bookmark to support.
(The reference source code of the blog can be found in the resources on my homepage. If you have any questions during the learning process, please feel free to ask me in the comment area)

Guess you like

Origin blog.csdn.net/HHX_01/article/details/132478155