• 重写equals()方法时,需要同时重写hashCode()方法


    package com.wangzhu.map;
    
    import java.util.HashMap;
    
    /**
     * hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,<br/>
     * 这样的散列集合包括HashSet、HashMap以及HashTable。<br/>
     * 能否可以直接根据hashCode值判断两个对象是否相等呢?<br/>
     * 答案:肯定是不可以的,因为不同的对象可能会生成相同的hashCode值。<br/>
     * 虽然不能根据hashCode值判断两个对象是否相等,但是可以直接根据hashCode值判断两个对象不等,<br/>
     * 如果两个对象的hashCode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,则必须通过equals方法。<br/>
     * 也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashCode值必定相等。<br/>
     * 如果equals方法得到的结果为,则两个对象的hashCode值不一定不同; <br/>
     * 如果两个对象的hashCode值不等,则equals方法得到的结果必为;<br/>
     * 如果两个对象的hashCode值相等,则equals方法得到的结果未知。<br/>
     * 
     * @author wangzhu
     * @date 2015-2-1下午11:22:42
     * 
     */
    public class DemoMap2 {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            Student stu = new Student(21, "John");
            HashMap<Student, Integer> map = new HashMap<Student, Integer>();
            map.put(stu, 1);
            System.out.println(map.get(stu));// 1
            System.out.println(map.get(new Student(21, "John")));// 1
            /**
             * 若Student只重写equals方法而没有没有重写hashCode方法时,则输出为null
             */
    
            stu.setAge(22);
            System.out.println(map.get(stu));// null
            /**
             * 在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,<br/>
             * 那么对这同一个对象调用多次, hashCode方法必须始终如一地返回同一个整数。<br/>
             * 
             * 设计hashCode()时最终稿的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。<br/>
             * 如果在将一个对象用put()添加进HashMap时产生一个hashCode值,而用get()取出时却产生另一个hashCode值,<br/>
             * 那么就无法获取该对象了。所以如果你的hashCode方法依赖于对象中易变的数据,用户就要当心了,<br/>
             * 因为此数据变化时,hashCode() 方法就会生成一个不同的散列码。<br/>
             */
        }
    
    }
    
    class Student {
        int age;
        String name;
    
        public Student(int age, String name) {
            super();
            this.age = age;
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = (prime * result) + age;
            result = (prime * result) + ((name == null) ? 0 : name.hashCode());
            return result;
        }
    
        /**
         * 重写时,需要让equals方法与hashCode方法始终在逻辑上保持一致性。
         */
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (this.getClass() != obj.getClass()) {
                return false;
            }
            Student other = (Student) obj;
            if (age != other.age) {
                return false;
            }
            if (name == null) {
                if (other.name != null) {
                    return false;
                }
            } else if (!name.equals(other.name)) {
                return false;
            }
            return true;
        }
    
    }

    下面是HashMap中的put方法【JDK1.6】

        public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key.hashCode());
            int i = indexFor(hash, table.length);
            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;
        }

    备注:put方法是用来向HashMap中添加新的元素。从put方法的具体实现可知,其会先调用hashCode方法得到该元素的hashCode值【经过处理的】,然后查看其是否存在于table数组中,如果存在则调用equals方法来确定是否是存在该元素;如果存在,则更新value值,否则将新的元素添加到HashMap中。

    下面是HashMap中的get方法【JDK1.6】

     public V get(Object key) {
            if (key == null)
                return getForNullKey();
            int hash = hash(key.hashCode());
            for (Entry<K,V> e = table[indexFor(hash, table.length)];
                 e != null;
                 e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                    return e.value;
            }
            return null;
        }

    备注:get方法是用来将HashMap中对应Key的值Value取出来。从get方法的具体实现可知,其会先调用hashCode方法得到该元素的hashCode值,然后查看其在table数组中是否存在,如果存在则调用equals方法来确定是Key对应的元素,并返回其Value,否则返回null。

  • 相关阅读:
    Android · SQLite
    Android · 获取网络图片
    Android · 广告走灯
    Android · 动画
    Android常用资源
    Android · Fragment
    JSP 自动刷新
    JSP 点击量统计
    JSP 页面重定向
    JSP 日期处理
  • 原文地址:https://www.cnblogs.com/xiaoxian1369/p/4266599.html
Copyright © 2020-2023  润新知