`
xm_king
  • 浏览: 395348 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
Group-logo
Spring技术内幕读书笔...
浏览量:15658
社区版块
存档分类
最新评论

HashCode和equals方法深度分析

    博客分类:
  • JAVA
阅读更多

 

         在往HashSet集合中放数据的时候,由于HashSet底层是用HashMap中的Key属性存储的,所以是不能重复的,那他如何判断其不是重复的元素呢.这个时候他判断有两步.

       1.调用元素的hashcode 方法,判断两对象的hashCode 是否相等,如果不相等,则认为两对象不相等,结束.如果相等,则转入equals 方法进行判断.

       2.如果equals 方法返回true则,是相等的.如果返回false则是不相等的.结束.这里是最终结果.

       总的归纳是如果在调用hashCode 方法时判断了对象不相等那就有了结论.不用调用equals 方法了

 

 如要以上推论成立,需要验证四个结论:

        1.这个hashCode 方法中返回的结果是永远也不相等的,因此会调用equals 方法进行判断,结果是所有元素都打印出来了.

        2.hashCode 方法不变,修改equals 方法,让其总返回false,结果和1一样.

---->以上两点成立的话,说明hashCode 方法返回的值不相等的话,结果就与equals 方法无关了.

        3.当把hashCode 方法中返回数改成一常量时,equas方法总return false,结果是返回第一个元素;

        4.当把hashCode 方法中返回数改成一常量时,equas方法总return ture 结果返回全部元素.

----->以上两点成立的话,说明hashCode 方法返回的值相等的话,结果有equals 方法控制.

import java.util.HashSet;
import java.util.Iterator;
public class TestHashSet {
 
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  HashSet hs  = new HashSet();
  String a="123";
  hs.add(new Element(a,"mengchao"));
  hs.add(new Element(a,"mengchao"));
  hs.add(new Element("1234","mengchao3"));
  Iterator it=hs.iterator();
  while(it.hasNext())
  {
   System.out.println(it.next());
  }
 }
}

class Element{
 
 private String num;
 private String name;
 static int i=0;
 public Element(String num,String name){
  this.num=num;
  this.name=name;
 }
 
 public String toString(){
  return "学号为:"+num+";————名字为"+name;
 }
 public int hashCode(){
  return i++;
 }
 public boolean equals(Object o){
  Element os = (Element)o; 
  return true;
 }
}

结果:
学号为:1234;————名字为mengchao3
学号为:123;————名字为mengchao
学号为:123;————名字为mengchao
 

       将equals 方法中  return true; 改成  return false;结果还是一样.

import java.util.HashSet;
import java.util.Iterator;

public class TestHashSet {
 
 

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  HashSet hs  = new HashSet();
  String a="123";
  hs.add(new Element(a,"mengchao"));
  hs.add(new Element(a,"mengchao"));
  hs.add(new Element("1234","mengchao3"));
  
  Iterator it=hs.iterator();
  
  while(it.hasNext())
  {
   System.out.println(it.next());
  }

 }

}


class Element{
 
 private String num;
 private String name;
 //static int i=0;
 public Element(String num,String name){
  this.num=num;
  this.name=name;
 }
 
 public String toString(){
  return "学号为:"+num+";————名字为"+name;
 }
 public int hashCode(){
  return 3;
 }
 public boolean equals(Object o){
  Element os = (Element)o; 
  return true;
  
 }
}
运行结果:

学号为:123;————名字为mengchao
 

        将equals 方法中  return true; 改成  return false;

 

运行结果:

学号为:1234;————名字为mengchao3
学号为:123;————名字为mengchao
学号为:123;————名字为mengchao

       在Object类中定义的几个hashCode约定如下:
       1. 在同一应用中,一个对象的hashCode函数在equals函数没有更改的情况下,无论调用多少次,它都必须返回同一个整数。
       2. 两个对象如果调用equals函数是相等的话,那么调用hashCode函数一定会返回相同的整数。
       3. 两个对象如果调用equals函数是不相等的话,那么调用hashCode函数不要求一定返回不同的整数。

         补充一点我自己的看法,拿HashMap来举例,

       在HashMap中保存元素的值是一个 transient Entry[] table,也就是一个数组。在这里要特别注意Entry的元素,在Entry中它有一个属性next,记录了和本节点具有相同的Hash码的对象。但是它们的Equals方法返回的是false。这也解释了为什么先去判断HashCode值,还要再去判断equals方法了。

          在往HashMap中加入数据的过程是这样的,首先要根据key的hashcode值,根据一定的散列算法,找到对应table上的位置,如果该位置已经有value存在了,那么,判断旧value的key和新插入值的key的equals方法是否相等,如果相等,把旧value替换成新插入值。key不变(因为hashcode和equals都相等,HashMap就认为这两个key是相等的)。如果不相等,则将旧value的entry的next属性设置为新value对应的entry属性(实际上这就是解决hash冲突的一种方法)。

            从HashMap中取出元素的过程和上面刚好相反,在这里就不叙述了。

分享到:
评论

相关推荐

    set接口经常用的hashCode和equals方法详解

    ### set接口中hashCode和equals方法详解 #### 一、引言 在Java编程语言中,`Set`接口作为集合框架的重要组成部分,在实现无重复元素的数据结构方面扮演着关键角色。为了确保元素的唯一性,`Set`接口依赖于对象的`...

    【面试】hashCode与equals两者之间的关系 / == 和equals / 为什么要重写equals方法 / 重写equals /hashcode方法 / 为什么要重写hashCode方法

    【面试】中提到的几个关键知识点集中在对象比较、equals()和hashCode()方法的使用以及它们之间的关系上。这些概念在Java编程中至关重要,特别是在处理集合类和比较对象时。 1、**hashCode与equals两者之间的关系**...

    Java常见笔试、面试题目深度剖析 相等性(==及equals方法)详解

    在Java编程语言中,相等性是理解和使用对象时至关重要...对于自定义类,重写equals()和hashCode()方法是必要的,以确保对象的比较逻辑正确无误。了解这些基础知识,能够让你在面对Java相关的面试或编程挑战时更加自信。

    java中的哈希算法和hashcode深入讲解1

    从实现上来说,java是借助hashcode()方法和equals()方法来实现判断元素是否已经存在的。当我们向HashMap中插入元素A时,首先,调用hashcode()方法,判断元素A在容器中是否已经存在。如果A元素的hashcode值在HashMap...

    Java常见笔试、面试系列深度剖析第六讲

    本讲将深度剖析Java中的"==运算符"和"equals()方法",这两个是判断对象之间相等性的主要手段。 一、"=="运算符 "=="运算符在Java中用于比较基本类型的值是否相等,例如int、char、boolean等。对于引用类型的变量,...

    Java常见笔试,面试题目深度剖析

    `equals()`和`hashCode()`方法是判断对象相等和实现哈希表的关键。面试题可能涉及它们的重写规则,以及为何要在重写`equals()`时同时重写`hashCode()`。 ### 方法重写(Override) 方法重写是子类继承父类时对父类...

    面试基础总结.docx

    JavaSE是Java编程的基础部分,面试中经常涉及的Java基础知识包括变量存储位置、equals和hashcode的重写、Map的分类及其特点、Object的hashCode方法、以及==运算符的使用等。以下是对这些知识点的详细解释: 1. **...

    2021最新版数据结构与算法面试题手册 1.pdf

    5. **hashCode()和equals()方法的重要性**:在HashMap中,hashCode()方法用于确定键值对的索引,而equals()方法用于比较两个键是否相等。如果两个不同的对象通过hashCode()方法得到的哈希值相同,且equals()方法返回...

    复杂对象的比较

    Java 7引入了`java.util.Objects`类,其中的`equals()`方法可以方便地比较基本类型和对象,而`deepEquals()`方法用于比较两个对象数组或复杂嵌套的对象结构,它会进行深度比较。 **5. 实现Comparable接口** 除了`...

    八张图深度理解Java特性

    equals() 方法和 hashCode() 方法是 Java 中两个非常重要的方法,它们的作用是分别比较两个对象的值和哈希值。图 2 展示了这两个方法的区别: * 如果两个对象相等(equal),那么他们一定有相同的哈希值。 * 如果两...

    java(BAT)面试题汇总

    hashCode和equals方法的关系是Java中判断对象是否相等的两个重要方法。如果两个对象equals比较为相等,那么它们的hashCode值也必须相等。但是,如果两个对象的hashCode值相等,并不代表这两个对象equals比较也为相等...

    java面试题及其答案

    - **反射(Reflection)**:了解如何在运行时动态访问类、方法和字段,以及反射在动态代理、配置文件解析等方面的应用。 - **IO流**:熟悉字节流和字符流的区别,了解NIO(New IO)与BIO(Blocking IO)的不同之处...

    Java初级面试题.docx

    当两个对象的hashCode()相等时,它们可能不是同一个对象,因此还需要通过equals()方法进行深度比较。String、StringBuffer和StringBuilder都是用来处理字符串的类,其中String是不可变的,而StringBuffer和...

    基于Druid的SqlParser模块解析create table语句创建java POJO和DAO类的效率工具.zip

    4. 可能还包括构造函数、toString()、equals()和hashCode()等常用方法。 生成DAO类的过程中,会包含以下内容: 1. 定义接口,接口中的方法对应于基本的CRUD(Create、Read、Update、Delete)操作,如insert()、...

    接口与Object类

    这意味着每一个自定义类,默认情况下都是Object类的子类,即使没有显式声明也继承了Object类的所有属性和方法。 #### toString() 方法 `toString()` 方法用于返回对象的字符串表示形式,通常用于打印或调试目的。...

    Android知识体系梳理(4)-Java基础篇-Object方法分析,String的深度解析,String Pool分析,与StringBuilder、StringBuffer的对比

    首先,Object类是所有Java类的基类,它定义了一些基础方法,如`equals()`、`hashCode()`、`clone()`和`toString()`。`equals()`方法默认比较的是对象的引用,也就是判断两个对象是否是同一个实例。在自定义类中,...

    Java常见笔试、面试题目深度剖析

    - **equals()与hashCode()**:在"相等性(==及equals方法)详解.swf"中,会深入讨论这两个方法的区别和何时重写它们。 3. **异常处理** - **try-catch-finally**:理解如何捕获和处理异常,以及finally块的作用。...

Global site tag (gtag.js) - Google Analytics