在往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方法详解 #### 一、引言 在Java编程语言中,`Set`接口作为集合框架的重要组成部分,在实现无重复元素的数据结构方面扮演着关键角色。为了确保元素的唯一性,`Set`接口依赖于对象的`...
【面试】中提到的几个关键知识点集中在对象比较、equals()和hashCode()方法的使用以及它们之间的关系上。这些概念在Java编程中至关重要,特别是在处理集合类和比较对象时。 1、**hashCode与equals两者之间的关系**...
在Java编程语言中,相等性是理解和使用对象时至关重要...对于自定义类,重写equals()和hashCode()方法是必要的,以确保对象的比较逻辑正确无误。了解这些基础知识,能够让你在面对Java相关的面试或编程挑战时更加自信。
从实现上来说,java是借助hashcode()方法和equals()方法来实现判断元素是否已经存在的。当我们向HashMap中插入元素A时,首先,调用hashcode()方法,判断元素A在容器中是否已经存在。如果A元素的hashcode值在HashMap...
本讲将深度剖析Java中的"==运算符"和"equals()方法",这两个是判断对象之间相等性的主要手段。 一、"=="运算符 "=="运算符在Java中用于比较基本类型的值是否相等,例如int、char、boolean等。对于引用类型的变量,...
`equals()`和`hashCode()`方法是判断对象相等和实现哈希表的关键。面试题可能涉及它们的重写规则,以及为何要在重写`equals()`时同时重写`hashCode()`。 ### 方法重写(Override) 方法重写是子类继承父类时对父类...
JavaSE是Java编程的基础部分,面试中经常涉及的Java基础知识包括变量存储位置、equals和hashcode的重写、Map的分类及其特点、Object的hashCode方法、以及==运算符的使用等。以下是对这些知识点的详细解释: 1. **...
5. **hashCode()和equals()方法的重要性**:在HashMap中,hashCode()方法用于确定键值对的索引,而equals()方法用于比较两个键是否相等。如果两个不同的对象通过hashCode()方法得到的哈希值相同,且equals()方法返回...
Java 7引入了`java.util.Objects`类,其中的`equals()`方法可以方便地比较基本类型和对象,而`deepEquals()`方法用于比较两个对象数组或复杂嵌套的对象结构,它会进行深度比较。 **5. 实现Comparable接口** 除了`...
equals() 方法和 hashCode() 方法是 Java 中两个非常重要的方法,它们的作用是分别比较两个对象的值和哈希值。图 2 展示了这两个方法的区别: * 如果两个对象相等(equal),那么他们一定有相同的哈希值。 * 如果两...
hashCode和equals方法的关系是Java中判断对象是否相等的两个重要方法。如果两个对象equals比较为相等,那么它们的hashCode值也必须相等。但是,如果两个对象的hashCode值相等,并不代表这两个对象equals比较也为相等...
- **反射(Reflection)**:了解如何在运行时动态访问类、方法和字段,以及反射在动态代理、配置文件解析等方面的应用。 - **IO流**:熟悉字节流和字符流的区别,了解NIO(New IO)与BIO(Blocking IO)的不同之处...
当两个对象的hashCode()相等时,它们可能不是同一个对象,因此还需要通过equals()方法进行深度比较。String、StringBuffer和StringBuilder都是用来处理字符串的类,其中String是不可变的,而StringBuffer和...
4. 可能还包括构造函数、toString()、equals()和hashCode()等常用方法。 生成DAO类的过程中,会包含以下内容: 1. 定义接口,接口中的方法对应于基本的CRUD(Create、Read、Update、Delete)操作,如insert()、...
这意味着每一个自定义类,默认情况下都是Object类的子类,即使没有显式声明也继承了Object类的所有属性和方法。 #### toString() 方法 `toString()` 方法用于返回对象的字符串表示形式,通常用于打印或调试目的。...
首先,Object类是所有Java类的基类,它定义了一些基础方法,如`equals()`、`hashCode()`、`clone()`和`toString()`。`equals()`方法默认比较的是对象的引用,也就是判断两个对象是否是同一个实例。在自定义类中,...
- **equals()与hashCode()**:在"相等性(==及equals方法)详解.swf"中,会深入讨论这两个方法的区别和何时重写它们。 3. **异常处理** - **try-catch-finally**:理解如何捕获和处理异常,以及finally块的作用。...