java 翻盖hashCode()深入探讨 代码演示样例

package org.rui.collection2.hashcode;
/**
* 覆盖hashcode
* 设计HashCode时最重要的因素 就是:不管何时,对同一个对象调用HashCode都应该产生相同的值,
* 假设你的HashCode方法依赖于对象中易变的数据,用户就要当心了,由于此数据发生变化 时
* HashCode就会生成一个不同的散列码,相当于产生一个不同的健
* 此外 也不应该使HashCode依赖于具有唯一性的对象信息,尤其是使用this的值,这仅仅能非常糟糕,
* 由于这样做无法生成一个新的健,使这与Put中原始的健值对中的健相同,它的默认的HashCode使用的是对象的地址
* 所以 应该 使用对象内有意义的识别信息
*
* 下面以String类为例 String对象都 映射到同一块内存域,
* 所以 new String("hello") 生成的两个实例 ,尽管是相互独立的,
* 可是对它们使用HashCode应该生成相同的结果,下面演示样例可以看到
* 对String而言,HashCode明显是基于String的内容的,
*
* 因此 要想使HashCode有用,它必须 速度快,而且必须有意义。也就是说,它必须基于对象的内容生成的散列码,
* 记得吗,散列码不必是独一无二的 (应该更关注生成速度,而不是唯一性)
* 但HashCode和Equals 必须可以全然确定对象的身份
* 所以散列码生成的范围并不重要,仅仅要是int就可以
* 还有别一个影响因素,好的HashCode应该产生分布均匀的散列码
*
*
* @author lenovo
*
*/ public class StringHashCode {
public static void main(String[] args) {
String[] hello="Hello Hello".split(" ");
System.out.println(hello[0].hashCode());
System.out.println(hello[1].hashCode());
}
}
/**output:
69609650
69609650
*/
package org.rui.collection2.hashcode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 覆盖hashcode
*
* 在Effective java programming language guide ....这本书 为如何写出一份像样的hashcode给出了基本指导
* 1,int变量result 赋予某个非零值 常 量,
* 2,为对象内每一个有意义的域f(即每一个能够做equlas操作的域) 计算一个int散列码c
* ----------------------------------------- -----------------------------------------
* 域类型 计算
* ----------------------------------------- -----------------------------------------
* boolean c=(f?0:1)
* byte,char,shor或int c=(int)f
* long c=(int)(f^(f>>>32))
* float c=Float.floatToIntBits(f); 依据 IEEE 754 浮点“单一格式”位布局,返回指定浮点值的表示形式
* double c=Double.doubleToLongBits(f);
* Object 其equals调用这个域的equlas c=f.hashCode();
* 数组 对每一个元素应用上述规则
*
* 3,合并计算得到的散列码
* 4,返加result
* 5检查hashcode最后生的结果。确保同样的地象有同样的散列码
* ----------------------------------------- -----------------------------------------
*
*
* CountedString是由一个String和id组成,此id代表包括同样String的CountedString对象的编号
* 全部的String被存储在ArrayList中,在构造器中通过迭代遍历此ArrayList完毕对Id的计算
*
* hashcode and equals都是基于CountedString的两 个域来生成的结果,假设它们仅仅是基于String或仅仅基于Id
* 不同的对象就可能产生同样的值
*
* 在Main中使用了同样的String,创建了多个CountedString对象,这说明,尽管String同样 ,
* 但因为Id不同,所以使得它们的散列码并不同样,
* @author lenovo
*
*/
public class CountedString {
private static List<String> created = new ArrayList<String>();
private String s;
private int id = 0; public CountedString(String str) {
s = str;
created.add(s);
// id is the total numbe of instances
// of this string in by CountedString
for (String s2 : created) {
if (s2.equals(s))
id++;
}
} public String toString() {
return "String:" + s + " id:" + id + " hashCode:" + hashCode();
} public int hashCode()
{
//the very simple approach
//return s.hashCode()*id;
//using joshua bloch's recipe//使用joshua bloch的配方
int result=17;
//合并计算得到散列码
result=37*result+s.hashCode();
result=37*result+id;
return result;
} public boolean equals(Object o) {
return o instanceof CountedString&&
s.equals(((CountedString)o).s)&&
id==((CountedString)o).id; }
public static void main(String[] args) {
Map<CountedString,Integer> map=new HashMap<CountedString,Integer>();
CountedString[] cs=new CountedString[5];
for(int i=0;i<cs.length;i++)
{
cs[i]=new CountedString("hi");
map.put(cs[i], i);//autobox int->Integer
}
System.out.println(map);
for(CountedString cstring:cs)
{
System.out.println("Looking up"+cstring);
System.out.println("map.get(cstring):"+map.get(cstring));
}
} }
package org.rui.collection2.hashcode;
/**
* 覆盖hashCode
*
* compareTo 方法有一个比較结构,因此它会产生一个排序序列,排序的规则首先依照实际类型排序
* 然后假设有名字的话,依照name排序,最后依照创建的顺序排序,
* @author lenovo
*
*/
public class Individual implements Comparable<Individual>{ private static long counter=0;
private final long id=counter++;
private String name; public Individual(String name){this.name=name;}
public Individual(){}
public String toString(){
return getClass().getSimpleName()+
(name==null?"":" "+name);
}
public long id(){return id;}
public boolean equals(Object o){
return o instanceof Individual&&
id==((Individual)o).id;
}
public int hashCode(){
int result=17;
if(name!=null)
result=37*result+name.hashCode();
result=37*result+(int)id;
return result;
}
@Override
public int compareTo(Individual o) {
String first=getClass().getSimpleName();
String argFirst=o.getClass().getSimpleName();
int firstCompare=first.compareTo(argFirst);
if(firstCompare!=0)
{
return firstCompare;
}
if(name!=null && o.name!=null)
{
int secondCompare=name.compareTo(name);
if(secondCompare!=0)
return secondCompare;
} return (o.id<id?-1:(o.id==id?0:1));
} }
package org.rui.collection2.hashcode;

import java.util.*;

import org.rui.classts.Pet;
import org.rui.classts.chilnd.*; /**
*
* 以下的演示样例说明了它怎样工作的;
*
* 因为全部的寵物都有名字,因此它們首先依照類型排序,然后在同類型中依照 名字排序
* 為新類編寫正確的hashCode和equals非常须要技巧,Apache的jakarta commons項目中有許多工具能够人幫助你完毕此事
* @author lenovo
*
*/ public class IndvidualTest { public static void main(String[] args) {
//Set<Individual> pets=new TreeSet<Individual>();
Pet p=new Cat("猫");
Pet p1=new Dog("狗");
Pet p2=new EgyptianMan("EgyptianMan");
Pet p3=new Manx("马恩岛猫");
Pet p4=new Pug("巴哥犬"); //一个人有非常多宠物
Map<Individual,List<? extends Pet>> list2=new HashMap<Individual,List<? extends Pet>>(); Individual in=new Individual("Dawn");
Individual in2=new Individual("東方不敗");
list2.put(in, Arrays.asList(p,p1,p2,p3,p4));
list2.put(in2, Arrays.asList(p2,p3,p4)); System.out.println(list2);//輸出這個人的寵物 //查找Dawn的寵物
List<? extends Pet> l=list2.get(in);
System.out.println(l); }
}
/**output:
{Individual 東方不敗=[Pet [name=EgyptianMan], Pet [name=马恩岛猫], Pet [name=巴哥犬]],
Individual Dawn=[Pet [name=猫], Pet [name=狗], Pet [name=EgyptianMan], Pet [name=马恩岛猫], Pet [name=巴哥犬]]}
[Pet [name=猫], Pet [name=狗], Pet [name=EgyptianMan], Pet [name=马恩岛猫], Pet [name=巴哥犬]]
*/

java 覆盖hashCode()深入探讨 代码演示样例的更多相关文章

  1. java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4

    java 线程  原子类相关操作演示样例 package org.rui.thread.volatiles; import java.util.Timer; import java.util.Time ...

  2. JAVA简单Swing图形界面应用演示样例

    JAVA简单Swing图形界面应用演示样例 package org.rui.hello; import javax.swing.JFrame; /** * 简单的swing窗体 * @author l ...

  3. Python Web框架Tornado的异步处理代码演示样例

    1. What is Tornado Tornado是一个轻量级但高性能的Python web框架,与还有一个流行的Python web框架Django相比.tornado不提供操作数据库的ORM接口 ...

  4. ArcSDE SDK For Java二次开发介绍、演示样例

    在一个工作中,遇到了须要java后台来查询ArcGIS 中用到的Oracle数据库空间数据,因为对ArcGIS空间数据首次接触,仅仅知道Oracle能够使用ST_GEOMETRY字段存储,例如以下图 ...

  5. java并行调度框架封装及演示样例

    參考资料:  阿里巴巴开源项目 CobarClient  源代码实现. 分享作者:闫建忠 分享时间:2014年5月7日 ---------------------------------------- ...

  6. Swift语言 简明基础 代码演示样例

    开发环境: Mac.Xcode6.0 下面内容均可创建ios common line项目来測试 1.Hello World演示样例 使用xcode创建新的common line项目,查看主文件main ...

  7. Java中普通代码块,构造代码块,静态代码块的代码演示样例及区分

    //运行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 当中静态代码块仅仅运行一次.构造代码块在每次创建对象是都会运行. 1 普通代码块 <span ...

  8. android动画-动画分类及代码演示样例

    原来一直对动画一知半解,仅仅知道依照网上的方法会用即可了,可是自己写起来感觉确实有点费劲,今天最终研究了代码实现,一下子感觉清晰多了.先把总结例如以下,代码中有具体的凝视. 动画分类 1.Peoper ...

  9. 【甘道夫】Eclipse+Maven搭建HBase开发环境及HBaseDAO代码演示样例

    环境: Win764bit Eclipse Version: Kepler Service Release 1 java version "1.7.0_40" 第一步:Eclips ...

随机推荐

  1. SharePoint 2010 列表项事件接收器 ItemAdded 的使用方法

    列表项事件处理器是继承于Microsoft.SharePoint.SPItemEventReceiver的类,Microsoft.SharePoint.SPItemEventReceiver类提供了许 ...

  2. 数组乘积--满足result[i] = input数组中除了input[i]之外所有数的乘积(假设不会溢出

    数组乘积(15分) 输入:一个长度为n的整数数组input 输出:一个长度为n的整数数组result,满足result[i] = input数组中除了input[i]之外所有数的乘积(假设不会溢出). ...

  3. web自动化框架之四测试报告的搭建

    现状: 看过前面的文章,楼主用的是python,所以在搭建测试报告这块的时候使用的是unittest+htmlTestRunner:然后发现生成出来的报告,总是有那么不完美的地方,比如想增加图片,比如 ...

  4. C#汉字转换拼音技术详解

    C#汉字转换拼音技术详解(高性能) 下面将源代码贴出.public static class ChineseToPinYin           {               private sta ...

  5. ubuntu开发软件的安装

    今天下午发现ubuntu12.04坏了,无奈只能重新安装,建议读者配置自己的ubuntu后备份一个,免得坏了重新安装,花了两个小时才把ubuntu的交叉环境弄好,其中搭建了tptp通信协议,还有arm ...

  6. BS与CS的联系与区别

    C/S是Client/Server的缩写.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系统,如Oracle.Sybase.InFORMix或SQL Server.客户端需要安装专用的客 ...

  7. Tkinter教程之Checkbutton篇

    本文转载自:http://blog.csdn.net/jcodeer/article/details/1811306 #Tkinter教程之Checkbutton篇#Checkbutton又称为多选按 ...

  8. BootStrap入门教程 (三) :可重用组件(按钮,导航,标签,徽章,排版,缩略图,提醒,进度条,杂项)

    上讲回顾:Bootstrap的基础CSS(Base CSS)提供了优雅,一致的多种基础Html页面要素,包括排版,表格,表单,按钮等,能够满足前端工程师的基本要素需求. Bootstrap作为完整的前 ...

  9. 依赖包bcrypt安装Issues

    说明:本文在个人博客地址为edwardesire.com,欢迎前来品尝. 在决策树项目中,使用到了bcrypt依赖包来加密文件.在wini8(win7)部署安装这个依赖的时候容易出现出现了问题. 解决 ...

  10. 第二百八十九天 how can I 坚持

    今天好伤啊,太把自己当回事了. 现在在弟弟这,下午和他一块看了看西客站附近的房子,感觉暂时好难,只是暂时的,一切都会好起来的. 弟弟上班也挺不容易,不该来给他添麻烦,替他心疼. 确实不知道该咋办了,好 ...