java.util.HashMap的簡單介紹


1. java.util.HashMap的底層實現是數組+鏈表。

2. 簡介put(key, value)方法的執行過程:
  1)通過key值,使用散列算法計算出來一個hash值,用來確定該元素需要存儲到數組中的哪個位置(index)。
  2)根據計算出來的位置(index),可以查看該位置是否被占用:
    2.1)如果位置(index)未被占用,將(key\value)封裝成一個節點,保存到該位置。
    2.2)如果位置(index)被占用,使用key和鏈表中的節點一一比較:
      ---->如果鏈表中不存在該key,將(key/value)封裝成節點添加到該鏈表中。
      ---->如果鏈表中已存在該key,替換該key對應節點的value值。

 

3. 簡介get(key)方法的執行過程:
  1)通過key的hash值可以計算出當前元素所在鏈表存儲在數組中的位置(index)。
  2)通過key值和鏈表中的節點一一比較,可以得到key值對應的元素。

 

4. 可以看出:
  1)key的hashCode方法很重要。因為要根據hashCode的值計算該元素要存在數組中的那個位置(index)。
  2)key的equals方法很重要。因為要根據equals方法來比較,數組某個位置的鏈表中是否已包含該元素(節點)。
   所以:
  key/value一旦存入到map當中,不能再去改變key的值。
  一旦改變了key的值(比如說改變key中某個用來生成hashCode的屬性),就不能根據這個key來找到元素存在數組中的位置了。

 

5. 一般做法:
  1)需要重寫key對象類的hashCode方法。最好用可以唯一標識該對象的屬性來生成hashCode。
  2)需要重寫key對象的equals方法。可以用唯一標識的一個或多個屬性來重寫equals方法。如果不重寫equals方法,對象比較時,會比較在內存中的地址。

 

一小段代碼:

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

import org.junit.Before;
import org.junit.Test;

public class TestMap {

    Map<User, Integer> map;
    User user1;
    User user2;
    User user3;

    @Before
    public void before() {
        map = new HashMap<User, Integer>();
        user1 = new User("320381", "zhangSan", 20);
        user2 = new User("320382", "LiSi", 22);
        user3 = new User("320383", "Wangwu", 25);

        map.put(user1, 1);
        map.put(user2, 2);
        map.put(user3, 3);
    }

    // 先看看map里都有什么
    @Test
    public void test1() {
        System.out.println(map);
        // {320383-Wangwu=3, 320381-zhangSan=1, 320382-LiSi=2}
    }

    // 改變了key值,再執行刪除操作,刪不掉了
    @Test
    public void test2() {
        user1.setIdCardNo("320384");
        map.remove(user1);
        System.out.println(map);
        // {320383-Wangwu=3, 320384-zhangSan=1, 320382-LiSi=2}
    }

    // 遍歷map-方法1
    @Test
    public void test3() {
        for (User user : map.keySet()) {
            System.out.println(user);
            System.out.println(map.get(user));
        }
    }

    // 遍歷map-方法2
    @Test
    public void test4() {
        for (Entry<User, Integer> en : map.entrySet()) {
            System.out.println(en.getKey());
            System.out.println(en.getValue());
        }
    }
}

class User {
    private String IdCardNo;
    private String name;
    private int age;

    public User() {
        super();
    }

    public User(String idCardNo, String name, int age) {
        super();
        IdCardNo = idCardNo;
        this.name = name;
        this.age = age;
    }

    // 重寫了hashCode方法 public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((IdCardNo == null) ? 0 : IdCardNo.hashCode());
        return result;
    }

    // 重寫了equals方法 public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (IdCardNo == null) {
            if (other.IdCardNo != null)
                return false;
        } else if (!IdCardNo.equals(other.IdCardNo))
            return false;
        return true;
    }

    // 重寫了toString方法 public String toString() {
        return IdCardNo + "-" + name;
    }

  // getters/setters(略)
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM