`
ganjp
  • 浏览: 72174 次
  • 性别: Icon_minigender_1
  • 来自: 其实还可以
社区版块
存档分类
最新评论

effective Java之【改写equals方法总是要改写hasCode()方法】

阅读更多

       在每一个改写了equals()方法的类中,你必须也要改写hashCode()方法。 不这么做的话 违反了Object.hasCode()的通用约定,从而导致该类无法与所有基于散列值(hash)的集合类结合一起正常运作(如:HashMap HashSet 和HashTable)

 

   java.lang.Object中约定的 hashCode的规范:

 1.一个应用程序执行过程中,一个对象的equals方法所作比较的信息没有被修改的话,那么调用多次hashCode方法返回的应该是同一个整数

2.如果通过equals放比较的两个对象相等 那么 两个对象的hasCode()方法返回的值必须相同

3.比较的两个对象不相同 可以返回相同的hasCode() 但是我们做程序应该尽量保证他们不相同,提高hashtable的性能。。

 

  例子:

写道
public class StaticUserGroupBean {

//要覆盖equals方法必须覆盖hasCode()
@Override
public boolean equals(Object obj) {
StaticUserGroupBean bean = (StaticUserGroupBean)obj;
if(bean.getStepId() == this.stepId &&
bean.getResourceName().equals(this.resourceName)) {
return true;
}
return false;
}
@Override
public int hashCode() {
int result = 11;
int c = getResourceName().hashCode() + getStepId();
return 31*result + c;
}

public String resourceName;
public int actionId;
public boolean isUser;
public int stepId;
public String getResourceName() {
return resourceName;
}
public void setResourceName(String resourceName) {
this.resourceName = resourceName;
}
public int getActionId() {
return actionId;
}
public void setActionId(int actionId) {
this.actionId = actionId;
}
public boolean isUser() {
return isUser;
}
public void setUser(boolean isUser) {
this.isUser = isUser;
}
public int getStepId() {
return stepId;
}
public void setStepId(int stepId) {
this.stepId = stepId;
}
}

 

 

 

这里重写了hashCode()散列函数,刚开始重写这个hasCode()方法的时候 我不知道如何去设计这个方法该返回什么值,根据一个好的散列函数的倾向:【为不相等的对象产生不同的散列码(hashCode)】..我抄袭了下一个简单的通用方法,当然可以自己设计:

 

   1.把某个非零证书,比如这里的11  保存到一个result 的int变量中 (这个result就是用来组装最后返回的散列值的)

   2.对于对象中每一个关键域(即equals方法中的进行比较的域 上例中的stepId和ResouceName)完成下面的操作:

     a.进行散列值的计算 c :

          i:boolean 类型的 f?0:1.

          byte char short 或者int行的 直接就是 (int)f

         long类型的(int)(f^(f>>>32)) 

         float >> Float.floatToIntBits(f)

        double>>(int)(Double.doubleToLongBits(f)^(Double.doubleToLongBits(f)>>>32))

       如果是引用对象 如:String 直接或者别的类型 直接返回对象的 hasCode()方法,因此要记得引用对象也要有相应的hasCode()方法的重写  String类型的话 简单的调用下 String.hasCode()方法。

     如果是数组的方法 循环每一个元素 按照上面给出来的规则去改写。

 3.return 37*result + c;

完成了这个方法之后  多检查几遍   是否相等的对象具有相等的hasCode。。

 

 上面出示话得值 11 是随便给的 可以根据自己的需要给出  为什么要给一个非零的初始值??我也不太明白 据说是可以避免一定的散列冲突。

 

 

其实上面那些我开始也不知道有啥用处,不就是判断是不是相等吗,有什么用吗?  其实挺有用的 比如:

   我们要去除List中的一些对象的重复值(当然这个重复的标准由你的equals方法去确定)  你会怎么去做 ??

 

 我们可以通过Set的特性,即没有重复的值 来快速进行去重复操作,而HashSet判断对象是否重复的标准就是equals()方法和hashCode()。所以重写hashCode()方法:

 

public class Test {
	
	public static void main(String[] args) {
		
		List list = new ArrayList();
		
		StaticUserGroupBean bean1  = new StaticUserGroupBean();
		bean1.setActionId(1);
		bean1.setResourceName("aaa");
		bean1.setStepId(2);
		bean1.setUser(false);
		
		StaticUserGroupBean bean2  = new StaticUserGroupBean();
		bean2.setActionId(1);
		bean2.setResourceName("aaa");
		bean2.setStepId(3);
		bean2.setUser(false);
		
		list.add(bean1);
		list.add(bean2);
		
		System.out.println(bean1.hashCode());
		System.out.println(bean2.hashCode());
		System.out.println(bean1.equals(bean2));
		list = removeCopys(list);
		for(int i = 0 ; i < list.size() ; i ++) {
			StaticUserGroupBean bean = (StaticUserGroupBean)list.get(i);
			System.out.println(bean.getActionId()  + "   " + bean.getResourceName() +  "   " + 
					bean.getStepId());
		}
	}
	
       //利用set的特性去除重复项  
	private static List removeCopys(List list) {
		Set set = new HashSet(list);    
                //把list清空 
		list.clear();  
               //再把去掉了重复值的list添加进来  
		list.addAll(set);    
		return list;
	}
}
 

 

分享到:
评论

相关推荐

    Java中equals方法隐藏的陷阱

    ### Java中equals方法隐藏的陷阱 在Java编程中,正确实现`equals`方法至关重要,它不仅影响对象的比较逻辑,还直接关系到集合类(如`HashSet`、`HashMap`等)的行为。本文将深入探讨Java中`equals`方法的一些常见...

    2.javaequals()方法.zip

    2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2....

    Effective Java第三版1

    《Effective Java》是Java编程领域的一本经典著作,由Joshua Bloch撰写,该书的第三版继续提供了关于如何编写高效、优雅、可维护的Java代码的指导。以下是基于给出的目录和部分内容提取的一些关键知识点: ### 第一...

    重写equals方法

    第二种情况:对于采用哈希算法的集合,集合中对象必须重写 hashCode 方法,同时也要重写 equals 方法。这是因为哈希算法需要使用 hashCode 方法来计算对象的哈希值,而 equals 方法用于判断两个对象是否相等。 如何...

    java中的==和equals()方法1

    在Java编程语言中,了解如何正确使用`==`和`equals()`方法是非常关键的,因为它们在比较对象和基本类型时有不同的行为。下面将详细解释这两个方法的工作原理、使用场景以及一些常见误区。 首先,`==`运算符主要用于...

    java中hashcode()和equals()方法详解

    在Java编程语言中,`hashCode()`和`equals()`方法是非常重要的概念,它们不仅对于深入理解Java内存管理至关重要,也是实现自定义类的关键部分之一。本文将详细介绍这两个方法的工作原理、使用场景以及它们之间的关系...

    重载equals方法示例

    重载equals方法示例重载equals方法示例重载equals方法示例重载equals方法示例重载equals方法示例

    effectiveJava课件分享

    4. 对于任何可能会暴露对象内部状态的方法(如toString、hashCode和equals),要确保它们不依赖于可变状态。 5. 如果类包含其他对象引用,确保这些对象也是不可变的,或者至少是不可变的视图。 例如,Java的String...

    equals方法的重写.docx

    `equals`方法是Java语言中Object类的一个重要成员方法,其默认实现是比较两个对象的内存地址是否相同(即是否为同一个对象)。为了使对象之间能够基于内容进行比较,通常需要在具体的类中重写`equals`方法。 #### ...

    effective java 读书笔记

    《Effective Java》是Java开发领域的经典著作,作者Joshua Bloch深入浅出地阐述了编写高效、健壮的Java代码的技巧和最佳实践。以下是对该书部分内容的详细解释: 1. **产生和销毁对象** - Item1:静态工厂方法相比...

    Java重写equals同时需要重写hashCode的代码说明

    Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.

    java_equals用法

    java_equals用法,用来熟悉重写equals方法的

    java中equals和==的区别

    Java 中 equals 和 == 的区别 Java 中的 equals 和 == 是两个不同的概念,很多开发者容易混淆它们。理解这两个概念的区别是非常重要的,因为它们对编程的正确性和性能都有很大的影响。 首先,我们需要了解 Java ...

    Java语言深入_equals

    Java中的`equals`方法是一个至关重要的方法,用于比较两个对象是否“相等”。在Java API规范中,`equals`方法必须遵循以下五个基本原则: 1. 对于任何引用类型,`o.equals(o)`总是返回`true`。 2. 如果`o.equals(o1...

    Java编程中避免equals方法的隐藏陷阱介绍

    Java编程中避免equals方法的隐藏陷阱介绍 Java编程中避免equals方法的隐藏陷阱介绍是一篇重要的技术文章,主要介绍了Java编程中避免equals方法的隐藏陷阱的技术。这篇文章将从equals方法的定义和重载开始,介绍了...

    Java_重写equals()和hashCode()

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们在很多场景下都发挥着至关重要的作用。这两个方法与对象的相等性比较和哈希表(如HashMap、HashSet)的运作紧密相关。这篇博客将深入...

    effective-java 配套代码

    《Effective Java》是Java开发领域的一本经典著作,由Joshua Bloch撰写,书中提出了一系列编程最佳实践和设计模式,帮助开发者写出更高效、更可靠、更易于维护的Java代码。配套代码`effective-java-examples-master`...

    Java 程序显示 equals() 方法的用法.docx

    在Java编程语言中,`equals()`方法是一个非常关键的成员函数,主要用于比较两个对象是否相等。这个方法在Java的Object类中定义,并且所有的Java类都默认继承了Object类,因此所有类的对象都可以使用`equals()`方法。...

    Java中的equals和hashCode方法详解1

    在Java编程语言中,`equals()`和`hashCode()`方法是对象的基本组成部分,它们主要用于对象的比较和存储。这两个方法在`java.lang.Object`类中定义,因此所有的Java类都默认继承了这两个方法。然而,根据具体的应用...

Global site tag (gtag.js) - Google Analytics