`
chensl
  • 浏览: 57970 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Collection之散列表(hash table)

阅读更多

链表和数组中元素是按一定次序进行排列的,散列表不在意元素的顺序,但是可以实现快速查找某个元素,散列表按照有利于其操作目的的原则组织数据。

散列表为每个对象计算一个整数,称为散列码(hash code),散列码是由对象的实例域产生的一个整数,具有不同数据域的对象将产生不同的散列码。

如果自己定义类,需要负责实现这个类的hashCode方法,自己实现的hashCode方法应该与equals方法兼容,即如果a.equals(b)为true,a必与b具有相同的散列码。散列码没有规律,如果x和y是两个不同的对象,那么x.hashCode()与y.hashCode基本上不会相同。String类使用下列算法计算散列码:

int hash = 0;
for(int i = 0; i<length();i++)
    hash = 31 * hash + charAt(i);

 由于hashCode方法定义在Object类中,因此每个对象都有一个默认的散列码,其值为对象的存储地址,看下面的例子:

String s = "Ok";
StringBuilder sb = new StringBuilder(s);
System.out.println(s.hashCode() + " " + sb.hashCode());
String t = new String("Ok");
StringBuilder tb = new StringBuilder(t);
System.out.println(t.hashCode() + " " + tb.hashCode());

 对应值为:

s      2556
sb    20526976
t       2556
tb     20527144

其中t和s具有相同的散列值,这是因为字符串的散列码是由内容导出的,而字符串sb和tb具有不同的散列码,是因为StringBuffer类中没有定义hashCode方法,它的散列码是由Object类的默认的hashCode方法导出的对象存储地址,所以不同。

如果重新定义equals方法,必须重新定义hashCode方法,以便用户可以将对象插入到散列表中。

hashCode方法应该返回一个整型数值,也可以是负数,并合理的组合实例域的散列码,以便能够让各个不同的对象产生的散列码更加均匀。

例如,下面Employee类的hashCode方法:

class Employee
{
    public int hashCode()
    {
    return 7 * name.hashCode()
    + 11 * new Double(salary).hashCode()
    + 13 * hireDay.hashCode();
    }
    . . .
}

 如果在数组类型的域,那么可以使用静态的Arrays.hashCode方法计算一个散列码,这个散列码由数组元素的散列码组成。

 

散列表可以用于实现几个重要的数据结构,其中最简单的是set类型,set是没有重复元素的元素集合,set的add方法首先在集中查找要添加的对象,如果不存在,就将这个对象添加进去。

Java集合类库提供了一个HashSet类,它实现了基于散列表的集,可以用add方法添加元素。contains方法已经被重新定义,用于在某个bucket中查找元素,不必查看集合中的所有的元素。

散列迭代器将依次访问所有的bucket,由于散列将元素分散在表的各个位置上,所以访问它们的顺序几乎是随机的,在不关心集合中元素的顺序时才应该使用HashSet。

下面的程序将从System.in读取单词,并添加到Set中,最后在打印部分单词及单词总数。可以使用一个普通文本文件示例进行运行测试,例如使用一个名称为 test.txt,里面包含几千个文本字符。

import java.util.*;
public class SetTest {

	/**
	 * 本程序通过使用HashSet散列集,计算文本文件中单词的个数并输出。
	 * @since 2010-09-03
	 * @author chensl
	 * @param args
	 */
	

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Set<String> words = new HashSet<String>();
		long totalTime = 0;
		
		Scanner in = new Scanner(System.in);
		while (in.hasNext())
		{
			String word = in.next();
			long callTime = System.currentTimeMillis();
			words.add(word);
			callTime = System.currentTimeMillis() - callTime;
			totalTime += callTime;
		}
		Iterator<String> iter = words.iterator();
		for (int i=1; i<=20; i++)
			System.out.println(iter.next());
		System.out.println("...");
		System.out.println(words.size()+" distinct words. " + totalTime + "milliseconds.");
	}
}

 

以上程序经过编译后,可以通过以下命令运行:

java SetTest < test.txt

 

输出结果类似于:


brave
attended
holding
begin.'
more.
REFUND
finished,'
lessons:
rumbling
lessons,
more,
'--it
cats.'
answered
'all
dropped,
'You
'Would
You're
THEIR
...
6014 distinct words. 16milliseconds.

分享到:
评论

相关推荐

    白话算法之散列表(Hash Table)从理论到实用.doc

    散列表(Hash Table)从理论到实用 散列表(Hash Table)是一种数据结构,它可以实现快速查找、插入和删除操作。下面是关于散列表的理论和实用知识点的总结。 散列表的定义 散列表是一种数据结构,它使用哈希函数...

    hash散列表的三种实现

    哈希表,也被称为散列表,是数据结构中一种高效的数据存储方式,它通过特定的哈希函数将关键字映射到一个固定大小的数组中,从而实现快速的查找、插入和删除操作。在IT领域,理解和掌握哈希表的实现方式至关重要,...

    在cuda上用gpu实现散列表

    散列表(Hash Table)是一种根据键值(Key-value)对存储数据的数据结构,其核心思想是通过散列函数将键值映射到表的一个位置来访问记录,这加快了查找速度。理想的散列函数应当均匀地分布数据,以减少冲突。 #### ...

    c语言或c++课程设计之散列表哈希表

    散列表(Hash Table)是一种数据结构,它通过特定的算法(哈希函数)将数据映射到一个固定大小的数组中,实现快速的查找、插入和删除操作。在C语言或C++中,掌握散列表哈希表的设计是提升编程能力的重要环节。本篇...

    线性散列表(linear hash)

    英文的讲线性hash的 ............ ............

    散列表之链接法解决冲突

    散列表(Hash Table)是一种数据结构,用于存储键值对,通过特定的散列函数将键(Key)转化为数组索引,实现快速访问。在实际应用中,由于散列函数的不完美,不同键可能会被映射到相同的索引位置,这种现象称为...

    SSD 5 hash table

    Sorting Hash Table Increase Sorting Searching Elementd in hash table BSTree

    散列表通讯录系统

    首先,我们要了解散列表(Hash Table)的基本概念。散列表是一种通过哈希函数将数据映射到数组中的数据结构,其核心优势在于快速查找和插入操作。它利用了“键-值”对的方式存储数据,通过计算键的哈希值确定元素在...

    散列表C++源程序代码

    散列表,又称哈希表,是一种在计算机科学中用于数据存储的数据结构,它通过使用哈希函数将键(key)映射到一个数组的特定位置,实现快速查找、插入和删除操作。在C++编程中,散列表常用于提高数据访问效率,因为它...

    散列表 (哈希表,线性探测再散列)

    给出的C语言代码实现了简单的散列表插入和查找功能,其中定义了`hashlist`类型用于表示散列表,`KeyType`类型用于表示关键字类型。具体实现步骤如下: 1. **初始化散列表**:`InitHashList`函数用于初始化散列表,...

    前端大厂最新面试题-hash-table.docx

    * 两数之和(811):通过 Hash Table 实现两数之和问题的解决。 * 无重复字符的最长子串(626):通过 Hash Table 实现无重复字符的最长子串问题的解决。 * 最长重复子串(1214):通过 Hash Table 实现最长重复子串...

    sanliebiao.rar_visual c_散列表_散列表实验

    散列表(Hash Table)是一种常用的数据结构,它通过散列函数将关键字映射到一个固定大小的数组中,实现快速的查找、插入和删除操作。在计算机科学中,尤其是在编程和数据结构的学习中,散列表占有重要地位。Visual ...

    散列表的设计与实现设计散列表实现电话号码查找系统。

    散列表是一种高效的数据结构,它通过哈希函数将键(key)映射到数组的索引位置,从而实现快速的查找、插入和删除操作。在这个电话号码查找系统中,散列表被用来存储电话号码和用户名作为关键字的记录,每个记录包含...

    c++,散列表的实现

    散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组...

    sanliebiao.rar_sanliebiao_散列表_散列表c++实现

    散列表(Hash Table)是一种非常重要的数据结构,它在计算机科学和编程中有着广泛的应用,尤其是在数据存储、查找和管理方面。散列表通过散列函数将关键字映射到数组的索引位置,从而实现了快速的插入、删除和查找...

    数据结构散列表编写的电话本及冲突处理源码

    散列表(Hash Table)是一种高效的数据结构,它通过哈希函数将数据映射到一个固定大小的数组中,实现了快速查找、插入和删除操作。在本话题中,我们主要讨论的是一个使用C语言实现的基于散列表的电话本管理系统,它...

    C++散列表实现电话本存储及查找功能

    在计算机科学中,数据结构是组织和管理大量数据的关键元素,而散列表(Hash Table)是一种高效的数据结构,尤其在快速查找、插入和删除操作上表现出色。在本项目"**C++散列表实现电话本存储及查找功能**"中,我们将...

    设计散列表实现电话号码查找系统

    至于提供的"hash_table"压缩包文件,它可能包含了项目的源代码,包括JavaFX的GUI组件和散列表相关的实现。通过查看和分析这些代码,可以更深入地理解上述概念是如何在实际项目中落地的。 综上所述,设计一个基于散...

    hash table

    方便地查看文件的MD5/SHA1值 – HashTab给文件属性窗口添加校验值!

Global site tag (gtag.js) - Google Analytics