Java 散列码

1.散列机制是如何工作的?
2.在使用散列容器时怎样编写hashCode()和equals()方法。


  1. 带有hash思想的容器,要求必须定义hashCode()。
  2. 你必须为散列存储和树型存储都创建一个equals()方法,但是hashCode()只有在这个类将会被置于HashSet或者LinkedHashSet中时才是必须的。
  3. 散列码是“相对唯一”的、用以代表对象的int值,他是通过将该对象的某些信息进行转换而生成的。
  4. HashCode()是根类Object中的方法,因此所有java对象都能产生散列码。
散列为何速度快?
  • 散列的价值在于速度:散列使得查询得以快速进行。
        (1)散列将键保存在某处,以便能够很快找到。存储一组元素最快的数据结构是数组,所以使用它来表示键的信息。但是因为数组不能调整容量,因此就有一个问题:我们希望在Map中保存数量不确定的值,但是如果键的数量被数组的容量限制了,该怎么办?
    答案就是:数组并不保存键本身。而是通过键对象生成一个数字,将其 作为数组的下标。这个数字就是散列码。由定义在Object中的、且可能由你的类覆盖的hashCode方法生成。
        (2)为解决数组容量被固定的问题,不同的键可以产生相同的下标。也就是说,可能会有冲突。因此,数组多大就不重要了,任何键总能在数组中找到它的位置。
        (3)于是查询一个值的过程首先就是计算散列码,然后使用散列码查询数组。如果能够保证没有冲突(如果哦值的数量是固定的,那么就有可能),那可就有了一个完美的散列函数,但是这种情况只是特例。通常,冲突由 外部连接 处理:数组并不直接保存值,而是保存值的list。然后对list中的值使用equals()方法进行线性的查询。这部分的查询自然会比较慢,但是,如果散列函数好的话,数组的每个位置就只有少量的值。因此,不是查询整个list,而是快速跳到数组的某个位置,只对很少的元素进行比较。这便是HashMap会如此快的原因。
        (4)由于散列表中的“槽位(slot)”通常称为“桶位(bucket)”,因此我们将表示实际散列表的数组名命为bucket。为了使散列分布均匀,桶的数量通常使用质数。注意,为了能够自动处理冲突,使用了一个LinkedList的数组;每一个新的元素只是直接添加到list末尾的某个特定桶位中。
        (5)另外,根据自己实际情况,可以对HashMap进行调优
如何编写hashCode()方法

    (1)设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该生成同样的值。它必须基于对象的内容生成散列码。散列码不必是唯一的,但是通过hashCode()和equals(),必须能够完全确定对象的身份。注意散列码是一个int对象。
    (2)好的hashCode()应该产生分布均匀的散列码。如果散列码都集中在一块,那么HashMap或者HashSet在某些区域的负载会很重,这样就不如分布均匀的散列码函数快。

  • 24
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于方法的电话号码查询系统的 Java 源代码示例: ``` import java.util.Hashtable; import java.util.Scanner; public class PhoneBook { private Hashtable<String, String> phoneBook = new Hashtable<String, String>(); public void addContact(String name, String phoneNumber) { phoneBook.put(name, phoneNumber); } public String findPhoneNumber(String name) { return phoneBook.get(name); } public static void main(String[] args) { PhoneBook phoneBook = new PhoneBook(); phoneBook.addContact("John Smith", "555-1234"); phoneBook.addContact("Jane Doe", "555-5678"); phoneBook.addContact("Bob Johnson", "555-9999"); Scanner scanner = new Scanner(System.in); System.out.println("Enter name to find phone number: "); String name = scanner.nextLine(); String phoneNumber = phoneBook.findPhoneNumber(name); if (phoneNumber != null) { System.out.println("Phone number for " + name + " is " + phoneNumber); } else { System.out.println("Phone number not found for " + name); } } } ``` 该程序使用了 Java 中的 Hashtable 类来实现电话号码查询系统。通过 addContact 方法可以添加联系人及其电话号码,而 findPhoneNumber 方法可以根据联系人姓名查找其电话号码。 在 main 方法中,我们创建了一个 PhoneBook 对象并添加了一些联系人及其电话号码。然后,我们使用 Scanner 类从用户输入中获取要查找的联系人姓名,并使用 findPhoneNumber 方法查找其电话号码。如果找到了电话号码,则输出联系人姓名和电话号码,否则输出未找到电话号码的提示信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值