effectivejava5覆盖equals时总要覆盖hashcode

cutter_point cutter_point     2022-08-03     283

关键词:

package cn.xf.cp.ch02.item9;

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

public class PhoneNumber
{
    private final short areaCode;
    private final short prefix;
    private final short lineNumber;
    
    public PhoneNumber(int areaCode, int prefix, int lineNumber)
    {
        rangeCheck(areaCode, 999, "area code");
        rangeCheck(prefix, 999, "prefix");
        rangeCheck(lineNumber, 9999, "line number");
        this.areaCode = (short) areaCode;
        this.prefix = (short) prefix;
        this.lineNumber = (short) lineNumber;
    }
    
    private static void rangeCheck(int arg, int max, String name)
    {
        if (arg < 0 || arg > max)
            throw new IllegalArgumentException(name + ": " + arg);
    }
    
    @Override
    public boolean equals(Object o)
    {
        if (o == this)
            return true;
        if (!(o instanceof PhoneNumber))
            return false;
        PhoneNumber pn = (PhoneNumber) o;
        return pn.lineNumber == lineNumber && pn.prefix == prefix && pn.areaCode == areaCode;
    }
    
    /*
    @Override
    //至于为什么使用31,这个是推荐值,研究表明这个数字用起来性能比较好
    public int hashCode()
    {
        int result = 17;
        result = 31 * result + areaCode;
        result = 31 * result + prefix;
        result = 31 * result + lineNumber;
        return result;
    }
    */
    
    //如果一个对象不是经常变动,而且开销比较大的话,就要考虑吧散列码缓存在对象内部
    //用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。
    private volatile int hashcode;
    
    @Override
    public int hashCode()
    {
        int result = hashcode;
        if (result == 0)
        {
            result = 17;
            result = 31 * result + areaCode;
            result = 31 * result + prefix;
            result = 31 * result + lineNumber;
            hashcode = result;
        }
        
        return result;
    }
    
    public static void main(String[] args)
    {
        Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
        m.put(new PhoneNumber(707, 867, 5309), "Jenny");
        //这里不会返回jenny哦,会返回null,这个是因为put对象吧他们放到不同的散列桶中
        System.out.println(m.get(new PhoneNumber(707, 867, 5309)));
    }
}

 

第9条:覆盖equals时总要覆盖hashcode

在每个覆盖equals方法的类中,也必须覆盖hashCode方法。否则,会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常工作,包括HashMap,HashSet,Hashtbale。 hashCode约定内容:1.只要对象equals方法的比... 查看详情

java对象覆盖equals时总要覆盖hashcode

  在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。   hashCode的通用约定:  1在程序的执行过程中,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始... 查看详情

effectivejava第九条:覆盖equals时总要覆盖hashcode(代码片段)

先来看一个例子:PhoneNumer类publicclassPhoneNumberprivatefinalintareaCode;privatefinalintprefix;privatefinalintlineNumber;publicPhoneNumber(intareaCode,intprefix,intlineNumber)rangeCheck(areaCode,999,&# 查看详情

覆盖equals时总要覆盖hashcode

...规定:相等的对象必须具有相同的散列码hashCode假如将只覆盖equals方法,没覆盖hashCode方法的类用于HashMap中,将会出现问题,会出现get()方法返回时不是同一个对象这就相当于将对象put进一个散列桶,却在另一个散列桶get这个对... 查看详情

java:effectivejava学习笔记之覆盖equals时总要覆盖hashcode(代码片段)

Java覆盖equals时总要覆盖hashcode覆盖equals时总要覆盖hashcode1.什么是hashcode方法?2.hashcode相等与对象相等之间的关系:(保证设计是规范的前提下)3.为什么要覆盖hashcode3.1、覆盖equals时总要覆盖hashCode3.2、如何在覆盖... 查看详情

java实战源码解析为什么覆盖equals方法时总要覆盖hashcode方法(代码片段)

1、背景知识本文代码基于jdk1.8分析,《Java编程思想》中有如下描述:另外再看下Object.java对hashCode()方法的说明:/***Returnsahashcodevaluefortheobject.Thismethodis*supportedforthebenefitofhashtablessuchasthoseprovidedby*& 查看详情

java实战源码解析为什么覆盖equals方法时总要覆盖hashcode方法(代码片段)

1、背景知识本文代码基于jdk1.8分析,《Java编程思想》中有如下描述:另外再看下Object.java对hashCode()方法的说明:/***Returnsahashcodevaluefortheobject.Thismethodis*supportedforthebenefitofhashtablessuchasthoseprovidedby*& 查看详情

effectivejava目录

...引用避免使用终结方法finalizer对于所有对象都通用的方法覆盖equals时请遵守通用约定覆盖equals时总要覆盖hashCode始终要覆盖toString谨慎地覆盖clone考虑实现Comparabl 查看详情

如果在覆盖 Equals() 时未能覆盖 GetHashCode(),会出现啥问题? [复制]

】如果在覆盖Equals()时未能覆盖GetHashCode(),会出现啥问题?[复制]【英文标题】:WhatcangowrongifonefailstooverrideGetHashCode()whenoverridingEquals()?[duplicate]如果在覆盖Equals()时未能覆盖GetHashCode(),会出现什么问题?[复制]【发布时间】:2009-... 查看详情

24覆盖equals时请遵守通用约定

覆盖equals方法看似很简单,但是有许多覆盖方式会导致错误,并且后果非常严重。最容易的避免这类问题的方法就是不覆盖equals方法,这种情况下,每个实例都与它自身相等。如果你必须覆盖equals方法,那么请遵循:1、自反性... 查看详情

强制一个类覆盖 .equals 方法

】强制一个类覆盖.equals方法【英文标题】:Forceaclasstooverridethe.equalsmethod【发布时间】:2009-10-2309:14:46【问题描述】:我有一堆实现通用接口的类:Command。而这群类去了一个地图。为了让Map正常工作,我需要每个实现Command的类... 查看详情

覆盖 std::equal

】覆盖std::equal【英文标题】:Overridestd::equal【发布时间】:2014-05-2121:57:52【问题描述】:在为std::unordered_map的equal_to运算符提供专门化时,我想知道是否可以确定lhs或rhs中的哪一个是当前存储在hashmap中的数据?我想做这样的事... 查看详情

java:effectivejava学习笔记之覆盖equals时请遵守通用约定(代码片段)

Java覆盖equals时请遵守通用约定覆盖equals时请遵守通用约定1、为什么要覆盖equals2、需要覆盖equals方法的时机2.1、不需要覆盖equals方法的情况2.2、需要覆盖equals方法的情况2.2.1、自反性2.2.2、对称性2.2.3、传递性2.2.4、一致性2.2.5、... 查看详情

未调用 C#GetHashCode/Equals 覆盖

】未调用C#GetHashCode/Equals覆盖【英文标题】:C#GetHashCode/Equalsoverridenotcalled【发布时间】:2010-11-0622:42:14【问题描述】:我遇到了GetHashCode和Equals的问题,我已经为一个类覆盖了这些问题。我正在使用运算符==来验证两者是否相等... 查看详情

为啥 StringBuffer/StringBuilder 不覆盖 equals 或 hashCode?

】为啥StringBuffer/StringBuilder不覆盖equals或hashCode?【英文标题】:WhydoesStringBuffer/StringBuildernotoverrideequalsorhashCode?为什么StringBuffer/StringBuilder不覆盖equals或hashCode?【发布时间】:2012-06-2204:17:58【问题描述】:为什么StringBuffer/StringBu 查看详情

为啥我需要覆盖 Java 中的 equals 和 hashCode 方法?

】为啥我需要覆盖Java中的equals和hashCode方法?【英文标题】:WhydoIneedtooverridetheequalsandhashCodemethodsinJava?为什么我需要覆盖Java中的equals和hashCode方法?【发布时间】:2022-01-0303:47:55【问题描述】:最近我通读了这个DeveloperWorksDocumen... 查看详情

为啥我需要覆盖 Java 中的 equals 和 hashCode 方法?

】为啥我需要覆盖Java中的equals和hashCode方法?【英文标题】:WhydoIneedtooverridetheequalsandhashCodemethodsinJava?为什么我需要覆盖Java中的equals和hashCode方法?【发布时间】:2019-01-2205:47:01【问题描述】:最近我通读了这个DeveloperWorksDocumen... 查看详情

为啥 set.contains 不使用覆盖的 equals() 方法?

】为啥set.contains不使用覆盖的equals()方法?【英文标题】:Whyisset.containsnotusingoverridenequals()method?为什么set.contains不使用覆盖的equals()方法?【发布时间】:2020-04-1117:37:03【问题描述】:我有这样的课:classVertexcharv;charw;intcost;public... 查看详情