zoukankan      html  css  js  c++  java
  • 在HashMap或HashTable,实现自定义类型做Key

    在HashMap和HashTable中的key值是不允许重复的,否则新的value会覆盖旧的value,那么是如何判断key值是否重复的。我们先来看一下存值的put()函数

    public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
    
        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }
    

      判断key是否存在的时候,是先比较key的hashcode,然后再比较相等或equals的,如果原本已经存在对应的key,则直接改变对应的value,并返回旧的value。而如果对应的key原本不存在的话将调用addEntry将对应的key-value添加到Map中。addEntry传递的参数hash就是对应key的hashCode。 

    所以当用自定义类做key时,需要重写hashCode()和equals()方法才可以实现自定义键在HashMap中的查找。

    例子如下:

     1 import java.util.HashMap;
     2 import java.util.Iterator;
     3 import java.util.Map;
     4 import java.util.Map.Entry;
     5 
     6 //没有重写hashcode和equals
     7 class Person {
     8     String id;
     9     String name;
    10     public Person(String id, String name) {
    11         this.id = id;
    12         this.name = name;
    13     }
    14     public String toString() {
    15         return "id = " + id + " , name = " + name;
    16     }
    17 }
    18 //重写了hashcode和equals
    19 class Student {
    20     String id;
    21     String name;
    22     public Student(String id, String name) {
    23         this.id = id;
    24         this.name = name;
    25     }
    26     public int hashCode() {
    27         return id.hashCode();
    28     }
    29     public boolean equals(Object ob) {
    30         Student student = (Student)ob;
    31         if(student.id.equals(this.id)) {
    32             return true;
    33         }else {
    34             return false;
    35         }
    36     }
    37     public String toString() {
    38         return "id = " + id + " , name = " + name;
    39     }
    40 }
    41 public class HashMapTest {
    42     public static void main(String[] args) {
    43        testHashMapWithoutEquals();
    44        testHashMapWithEquals();
    45     }
    46     public static void testHashMapWithoutEquals() {
    47         Map<Person, String> hMap = new HashMap<Person, String>();
    48         Person person1 = new Person("123", "Tom");
    49         Person person2 = new Person("123", "Tom");
    50         hMap.put(person1, "address");
    51         hMap.put(person2, "address");
    52         Iterator iterator = hMap.entrySet().iterator();
    53         while(iterator.hasNext()) {
    54             Map.Entry entry = (Map.Entry) iterator.next();
    55             Person key = (Person) entry.getKey();
    56             String val = (String) entry.getValue();
    57             System.out.println("key = " + key + "  value = " + val);
    58         }
    59     }
    60     public static void testHashMapWithEquals() {
    61         System.out.println("*********************");
    62         Map<Student, String> hMap = new HashMap<Student, String>();
    63         Student student1 = new Student("123", "Tom");
    64         Student student2 = new Student("123", "Tom");
    65         hMap.put(student1, "address");
    66         hMap.put(student2, "address");
    67         Iterator iterator = hMap.entrySet().iterator();
    68         while(iterator.hasNext()) {
    69             Map.Entry entry = (Map.Entry) iterator.next();
    70             Student key = (Student) entry.getKey();
    71             String val = (String) entry.getValue();
    72             System.out.println("key = " + key + "  value = " + val);
    73         }
    74     }
    75 }

    例子转载自:http://blog.csdn.net/achiberx/article/details/73655737

  • 相关阅读:
    day 30 粘包 自定义报头
    day29 网络基础之网络协议和通信
    day28 面向对象的进阶 反射 和类的内置方法
    day 27 模块和包 面向对象的复习
    CGI,FastCGI,PHP-CGI和PHP-FPM的区别
    跨平台的移动应用开发引擎CrossApp简介
    element-ui组件中的select等的change事件中传递自定义参数
    关于setInterval和setTImeout中的this指向问题
    懒加载和预加载的区别
    vueX的五个核心属性
  • 原文地址:https://www.cnblogs.com/mingyao123/p/7344734.html
Copyright © 2011-2022 走看看