【ThinkingInJava】51、散列与散列码

/**
* 书本:《Thinking In Java》
* 功能:散列与散列码
* 文件:Groundhog.java
* 时间:2015年5月3日09:42:54
* 作者:cutter_point
*/
package Lesson17Containers;

public class Groundhog
{
	protected int number;	//保护类型,继承之后还是保护类型
	public Groundhog(int n) { number = n; }

	public String toString()
	{
		return "Groundhog #" + number;
	}
}

/**
* 书本:《Thinking In Java》
* 功能:散列与散列码
* 文件:Prediction.java
* 时间:2015年5月3日09:42:54
* 作者:cutter_point
*/
package Lesson17Containers;

import java.util.Random;

public class Prediction
{
	private static Random rand = new Random(47);
	private boolean shadow = rand.nextDouble() > 0.5;	//判断产生的数值的范围,nextDouble产生的值在0到1之间

	public String toString()
	{
		if(shadow)
			return "Six more weeks of Winter!";
		else
			return "Early Spring!";
	}
}
/**
* 书本:《Thinking In Java》
* 功能:散列与散列码,一个天气预报系统,将Groundhog和Prediction对象联系起来
* 文件:SpringDeterctor.java
* 时间:2015年5月3日09:42:54
* 作者:cutter_point
*/
package Lesson17Containers;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

import static net.mindview.util.Print.*;

public class SpringDeterctor
{
	public static <T extends Groundhog> void detectSpring(Class<T> type) throws Exception
	{
		Constructor<T> ghog = type.getConstructor(int.class);	//获取type中参数是Int的构造器,这个是反射
		Map<Groundhog, Prediction> map = new HashMap<Groundhog, Prediction>();
		for(int i = 0; i < 10; ++i)
		{
			//初始化map里面的值,第二个参数是随机产生的两种状况
			map.put(ghog.newInstance(i), new Prediction());
		}
		print("map = " + map);
		Groundhog gh = ghog.newInstance(3);
		print("Looking up prediction for " + gh);
		if(map.containsKey(gh))	//等会我们发现找不到3号
	      print(map.get(gh));
	    else
	      print("Key not found: " + gh);
	}

	public static void main(String[] args) throws Exception
	{
		detectSpring(Groundhog.class);
	}

}

输出:

map = {Groundhog #9=Six more weeks of Winter!, Groundhog #4=Six more weeks of Winter!, Groundhog #2=Early Spring!, Groundhog #7=Early Spring!, Groundhog #8=Six more weeks of Winter!, Groundhog #3=Early Spring!, Groundhog #1=Six more weeks of Winter!, Groundhog
#6=Early Spring!, Groundhog #5=Early Spring!, Groundhog #0=Six more weeks of Winter!}  obj1

Looking up prediction for Groundhog #3  obj1

Key not found: Groundhog #3  obj1

/*

* 无法找到3号原因:

* 问题出现在Groundhog自动继承基类Object,所以这里使用Object的hashCode方法生成散列码,而他默认的是使用对象的地址计算散列码,

* 因此,由Groundhog(3)生成的第一个实例的散列码和由Groundhog gh = ghog.newInstance(3);生成的第二个实例散列码是不同的

* 而我们是按后者进行查找的

*

* 解决:

* 只编写hashCode的方法的覆盖方法还是无法运行,除非你同时覆盖equals

*/

时间: 2024-09-30 16:25:18

【ThinkingInJava】51、散列与散列码的相关文章

容器深入研究 --- 散列与散列码(三)

如何覆盖hashCode(): 明白了如何散列之后,编写自己的hashCode()就更有意义了. 首先,你无法控制bucket数组的下标值的产生.这个值依赖于具体的HashMap对象的容量,而容量的改变与容器的充满程度和负载因子有关.hashCode()生成的结果,经过处理后称为桶位的下标. 设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值.如果在将一个对象用put()添加进HashMap时产生一个hashCode()值,而用get()

容器深入研究 --- 散列与散列码(一)

通常的: 当标准类库中的类被作用HashMap的键.它用的很好,因为它具备了键所需的全部性质. 当你自己创建用作HashMap的键的类,有可能会忘记在其中放置必须的方法,而这时通常会犯的一个错误. 例如:考虑一个天气系统,将Groundhog对象与Prediction对象联系起来. class Groundhog { protected int number; public Groundhog(int n) { number = n; } public String toString() { r

容器深入研究 --- 散列与散列码(二)

为速度而散列: SlowMap.java说明了创建一个新的Map并不困难.但正如它的名称SlowMap所示,它不会很快,如果有更好的选择就应该放弃它.它的问题在于对键的查询,键没有按照任何特定的顺序保存,所以只能使用简单的线性查询,而线性查询是最慢的查询方式. 散列的价值在于速度: 散列使得查询得以快速进行.由于瓶颈在于键的查询速度,因此解决方案之一就是保持键的排序状态,然后使用Collections.binarySearch()进行查询. 散列则更进一步,它将键保存在某处,以便能够很快的找到.

java 散列与散列码探讨 ,简单HashMap实现散列映射表运行各种操作示列

package org.rui.collection2.maps; /** * 散列与散列码 * 将土拔鼠对象与预报对象联系起来, * @author lenovo * */ //土拨鼠 public class Groundhog { protected int number; public Groundhog(int n) { number=n; } @Override public String toString() { return "Groundhog #" + number

java 散列与散列码探讨 ,简单HashMap实现散列映射表执行各种操作示列

package org.rui.collection2.maps; /** * 散列与散列码 * 将土拔鼠对象与预报对象联系起来, * @author lenovo * */ //土拨鼠 public class Groundhog { protected int number; public Groundhog(int n) { number=n; } @Override public String toString() { return "Groundhog #" + number

Java散列和散列码的实现

转自:https://blog.csdn.net/al_assad/article/details/52989525 散列和散列码 ※正确的equals方法应该满足的的条件: ①自反性:x.equals(x) 一定返回true: ②对称性:y.euqlas(x)为true,那么x.equals(y)一定为true: ③传递性:x.equals(y)为true,y.euqlas(z)为true,则z.equals(x)为true: ④一致性:如果x,y中用于等价比较的信息没有变化,那么无论调用y.

数据结构--散列排序--散列表

散列表 散列查找,我们又回到了查找, 编译的时候,涉及变量及属性的管理: 插入:新变量的定义 查找:变量的引用 实际上是动态查找问题,查找树AVL树. 两个变量名(字符串)比较效率不高.字符串的比较要一个一个的比下去,时间会比较长, 是否可以把字符串转换成数字,再处理,就快多了.就是散列查找的思想. 已知的查找方法: 顺序查找                                          O(N) 二分查找(静态查找,不适合动态查找)   O(log2N) 二叉搜索数    

字典:散列表、散列字典、关键字列表、集合与结构体

字典 散列表和散列字典都实现了Dict的行为.Keyword模块也基本实现了,不同之处在于它支持重复键. Eunm.into可以将一种类型的收集映射转化成另一种. defmodule Sum do def values(dict) do dict |> Dict.values |> Enum.sum end end hd = [ one: 1, two: 2, three: 3 ] |> Enum.into HashDict.new IO.puts Sum.values(hd) #=&g

为什麽我们一般会在自增列或交易时间列上建立聚集索引?

http://www.cnblogs.com/lyhabc/p/3533027.html 一般的交易系统里面我们都会以自增列或交易时间列作为聚集索引列,因为一般这些系统都是写多读少 每天的交易数据会不停的插入到数据库,但是读取数据就没有数据插入那么频繁 因为这些系统一般是写多读少,所以我们会选择在自增列或交易时间列上建立聚集索引 测试 测试环境:SQLSERVER2012 SP1  WINDOWS7 64位 我们来做一个测试,测试脚本如下: 1 --测试脚本 插入性能 2 USE [test]