由于是自定义类型,所以HashMap中的equals()方法和hashCode()方法都需要自定义覆盖。

不然内容相同的对象对应的hashCode会不同,无法发挥算法的正常功能,覆盖equals方法,应该就相当于c++重载==运算符来保证能判断是否相等。只不过java没有自定义重载运算符这个功能的,需要进行方法覆盖。

equals的方法原型是 boolean equals(Object o);注意括号内,因为是继承自Object类,覆盖的是超类的方法。hashCode的方法原型就是int hashCode();

先看一段代码:

import java.util.*;
class Pair<V,K>{
V first;
K second;
public Pair() {first = null;second = null;}
public Pair(V f,K s){
first = f;
second = s;
}
// public boolean equals(Object o) {
// if(!(o instanceof Pair))
// {
// return false;
// }
// Pair<V,K> pn = (Pair<V,K>)o;
// return pn.first.equals(first) && pn.second.equals(second);
// }
// public int hashCode() {
// return first.hashCode() + second.hashCode();
// }
}
public class Main { public static void main(String[] args) {
Pair<String,String> p = new Pair<>("a","b");
Pair<String,String> q = new Pair<>("a","b");
System.out.println(p.equals(q));
System.out.println(p.hashCode() + " " + q.hashCode());
Map<Pair<String,String>,Integer> map = new HashMap();
map.put(p, 1);
System.out.println(map.containsKey(q));
map.put(q, 2);
for(Pair<String,String> key : map.keySet()) {
System.out.println(map.get(key));
}
}
}

这段代码把覆盖重写的两个方法给注释掉了,然后判断了值相同的两个Pair对象p和q是否相等,并输出了他们的hashCode,同时把p放进建立的HashMap中,用q来判断p是否存在,再把q放入,并遍历map的values。答案是:

false
2018699554 1311053135
false
1
2

然后:

import java.util.*;
class Pair<V,K>{
V first;
K second;
public Pair() {first = null;second = null;}
public Pair(V f,K s){
first = f;
second = s;
}
public boolean equals(Object o) {
if(!(o instanceof Pair))
{
return false;
}
Pair<V,K> pn = (Pair<V,K>)o;
return pn.first.equals(first) && pn.second.equals(second);
}
public int hashCode() {
return first.hashCode() + second.hashCode();
}
}
public class Main { public static void main(String[] args) {
Pair<String,String> p = new Pair<>("a","b");
Pair<String,String> q = new Pair<>("a","b");
System.out.println(p.equals(q));
System.out.println(p.hashCode() + " " + q.hashCode());
Map<Pair<String,String>,Integer> map = new HashMap();
map.put(p, 1);
System.out.println(map.containsKey(q));
map.put(q, 2);
for(Pair<String,String> key : map.keySet()) {
System.out.println(map.get(key));
}
}
}

然后把注释去掉之后的结果是:

true
195 195
true
2

虽然说这里的hashCode重写的没有什么道理,但是至少值相同的两个对象他们的hashCode是相同的,这样在HashMap中第一关判断hashCode是否相同就过了,接着再遍历判断是否有值相同的元素,可以判断是否含有某个键值,并更新键值的value等等。

而且要注意equals的覆盖,参数列表不可以因为是对于Pair对象的判断就改成Pair p,这样只是重载了并不是覆盖。

java自定义类型 作为HashMap中的Key值 (Pair<V,K>为例)的更多相关文章

  1. 一个关于自定义类型作为HashMap的key的问题

    在之前的项目需要用到以自定义类型作为HashMap的key,遇到一个问题:如果修改了已经存储在HashMap中的实例,会发生什么情况呢?用一段代码来试验: import java.util.HashM ...

  2. Python开发【笔记】:如何在字典遍历中删除key值?

    数据遍历时不能犯傻系列 前言: 针对字典做一些操作时,有时会遇到下面的状况,列如我们需要把data中的key值根据replace中的映射关系进行替换(Caller替换为caller) data = { ...

  3. 【java基础 12】HashMap中是如何形成环形链表的?

    导读:经过前面的博客总结,可以知道的是,HashMap是有一个一维数组和一个链表组成,从而得知,在解决冲突问题时,hashmap选择的是链地址法.为什么HashMap会用一个数组这链表组成,当时给出的 ...

  4. 使用自定义类型做qmap,qhash的key

    map在STL中的定义 template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> ...

  5. Oracle自定义类型在C#中调用示例

    1.C#代码: 1)using Oracle.DataAccess.Types; using System; using System.Collections.Generic; using Syste ...

  6. React 中的key值

    在react中必须要有key值,key不是用来提升react的性能的,react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key p ...

  7. react中对于key值的理解

    1.key是用来帮助react识别哪些内容被更改.添加或者删除.key需要写在用数组渲染出来的元素内部,并且需要赋予其一个稳定的值.如果key值发生了变更,react则会触发UI的重渲染. 2.在相邻 ...

  8. JS 遍历JSON中每个key值

    JS 遍历JSON中的每个key值,可以按键值对进行存储: var myVar = { typeA: { option1: "one", option2: "two&qu ...

  9. iOS 中plist文件中配置key值冲突的现象

    iOS开发一些特殊的软件需要在项目中配置对应的key值,然而近期在项目中发现一个有意思的现象,苹果官方文档中提供的key值很多,但其实有一些彼此可能有冲突,当你同时配置了彼此冲突的key值,可能会出现 ...

随机推荐

  1. solr入门之pinyin4j源代码改写动态加入扩展词及整合进war项目中

    1.初始化时载入用户定义的字典 package net.sourceforge.pinyin4j; import net.sourceforge.pinyin4j.multipinyin.Trie; ...

  2. Ant Problem: failed to create task or type foreach 问题

    用eclipse导出android时总是会出现有类没有导出的现象,感觉非常麻烦,就用ant些了脚本.在eclipse中运行脚本没问题.可是在命令行下运行会出现 Problem: failed to c ...

  3. xml 操作

    /////////////////////////////////jaxp对xml文档进行解析/////////////////////////////////////////// 要操作的xml文件 ...

  4. 【翻译自mos文章】关于分区索引:Global, Local, Prefixed and Non-Prefixed

    来源于: Partitioned Indexes: Global, Local, Prefixed and Non-Prefixed (文档 ID 69374.1) APPLIES TO: Oracl ...

  5. HDU 2112 HDU Today(STL MAP + Djistra)

    题目链接:HDU Today 立即集训要開始,抓紧时间练练手,最短路的基础题,第一次用STL的map 题目非常水,可是错了N遍.手贱了.本题不优点理的就是把地名转化为数字 #include <i ...

  6. 【Java】 Spring依赖注入小试牛刀:编写第一个Spring ApplicationContext Demo

    0  Spring的依赖注入大致是这样工作的: 将对象如何构造(ID是什么?是什么类型?给属性设置什么值?给构造函数传入什么值?)写入外部XML文件里.在调用者需要调用某个类时,不自行构造该类的对象, ...

  7. 用canvas合成图片

    朋友圈有些分享功能是通过长按图片另存来实现的,就像淘宝内部要分享朋友圈的时候一样,这些图片可以用canvas来合成. 获取了img的dom对象以后,进行base64的转. //加载对象$page.ge ...

  8. iOS7 文本转语音 AVSpeechSynthesizer -转载-

    http://www.cnblogs.com/qingjoin/p/3160945.html iOS7 的这个功能确实不错.我刚试了下,用官方提供的API ,简单的几句代码就能实现文本转语音! Xco ...

  9. 解决UICollectionView的Cell复用引起的布局混乱问题

    解决UICollectionView的Cell复用引起的布局混乱问题   问题复现.gif 查了一下度娘发现没有好的解决办法,于是发动自己的聪明才智,终于找到如下解决办法(充分证明了自己动手丰衣足食啊

  10. Python中类方法、__new__方法和__init__方法解析

    在编程语言中创建一个类,有构造方法这样的一个术语.而在Python中,通常大家都认为__init__是构造方法,其实并不完全等同.在构建类中,有一个特殊的方法__new__,这个才能等同为构造方法. ...