• java.util.HashMap的简单介绍


    1. java.util.HashMap的底层实现是数组+链表。

    2. 简介put(key, value)方法的执行过程:
      1)通过key值,使用散列算法计算出来一个hash值,用来确定该元素需要存储到数组中的哪个位置(index)。
      2)根据计算出来的位置(index),可以查看该位置是否被占用:
        2.1)如果位置(index)未被占用,将(keyvalue)封装成一个节点,保存到该位置。
        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(略)
    }
  • 相关阅读:
    【WEBAPI】Passing multiple POST parameters to Web API Controller Methods
    【WEBAPI】常用参数传递方法总结
    JavaScript面向对象静态方法私有方法公有方法特权方法
    javascript 封装
    javascript 获取 浏览器body高宽
    Fiddler 教程
    预加载下一张图片
    div页面居中
    关于模块化加载
    chrome本地不能操作iframe
  • 原文地址:https://www.cnblogs.com/zj0208/p/6297306.html
Copyright © 2020-2023  润新知