java中的hashmap和hashcode

本文深入解析Java中HashMap的hashCode()方法及其在插入、查找、删除操作中的作用,包括自定义类如何实现hashCode()以确保高效性,并提供一个自定义类实现hashCode()的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于java中hashcode()的说明,wiki里讲的非常好:

http://en.wikipedia.org/wiki/Java_hashCode%28%29


HashMap是java的一个常用类。它和java中的所有collection一样,都支持泛型:

public HashMap<Integer, Student> buildMap(Student[] students) {
  HashMap<Integer, Student> map = new HashMap<Integer, Student>();
  for (Student s : students) map.put(s.getId(), s);
  return map;
 }

使用HashMap的目的是为了实现快速查找,插入和删除。HashMap的高性能来自于hash表,不清楚的同学先自行学习哈希函数,哈希表的概念。

如上面代码所示: map.put(s.getId(), s); 在HashMap中放入的是键值对。但这和dictionary很不同 (dictionary中保存的也是键值对)。

插入时,首先将s.getid(),也就是键值对中的key,传递给哈希函数HashCode(),运算后得到一个哈希值hashcode。hashcode是一个int值,它决定了键值对中的value会被存储在哈希表中的什么位置。

因此实际上HashMap中只存储了value,而key则表明了value所存储的地方。我们会用下面的语句在HashMap中查找:

map.get(12)

java会自动调用HashCode()函数,传入12,得到一个哈希值。从而得知value的存储位置并返回value。在本例中,则是返回了id是12的学生的instance。

因此HashMap中查找,插入,删除时,都需要使用HashCode()。


上例中的key是一个整数,key也可以是String,而java已经实现了对于String的hashCode()并自动调用它。但是如果key是自定义的类,则需要自己实现HashCode().

map.get(student1);

如果student这个类没有实现HashCode(),则java调用从Object继承下来的HashCode().但是这个方法对于student类来说,未必是一个合适的方式。因此正如wiki所说:

In the Java programming language, every class must provide ahashCode() method which digests the data stored in an instance of the class into a single hash value (a 32-bit signed integer).

下面是一个自定义的类所实现的HashCode()的例子(其中IsVip,aggregationLimit等等都是该类的成员变量。同时也可以注意到,当类的成员变量是另外一个自定义的类时,就会调用那个类的HashCode方法):


public int hashCode() {
        int result = bundleClass != null ? bundleClass.hashCode() : 0;
        result = 31 * result + (isVip ? 1 : 0);
        result = 31 * result + (isDaily ? 1 : 0);
        result = 31 * result + aggregationLimit;
        result = 31 * result + alertExclusionDays.hashCode();
        result = 31 * result + fileMetaDataList.hashCode();
        result = 31 * result + (folder != null ? folder.hashCode() : 0);
        result = 31 * result + (incrementalPattern != null ? incrementalPattern.hashCode() : 0);
        result = 31 * result + (fullPattern != null ? fullPattern.hashCode() : 0);
        result = 31 * result + (manifestPattern != null ? manifestPattern.hashCode() : 0);

        return result;
    }

这里顺便说一句,自定义的类往往还需要实现另外两个方式 toString() 和 equals().

强烈建议看看那个wiki,里面还提到了在java中,是如何计算String的哈希值的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值