java自定义类型 作为HashMap中的Key值 (Pair<V,K>为例)

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

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

equals的函数原型是 boolean equals(Object o);注意括号内。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,这样只是重载了并不会覆盖。

原文地址:https://www.cnblogs.com/8023spz/p/9392405.html

时间: 2024-09-29 08:15:14

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

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

在之前的项目需要用到以自定义类型作为HashMap的key,遇到一个问题:如果修改了已经存储在HashMap中的实例,会发生什么情况呢?用一段代码来试验: import java.util.HashMap; import java.util.Map; public class TestHashMap { public static void main(String[] args) { testObjAsKey(); } private static void testObjAsKey() { c

java多线程之从任务中获取返回值

package wzh.test; import java.util.ArrayList; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; class TaskWithResult implements Callable<Strin

Java自定义类型作为HasMap的key的查找

最近常常会用到一些之前看过却没有实际去实现的小细节,深有感慨(掌握一门技术绝不是看一遍就够了,一遍远远不够,远远不够........), 言归正传,先直接上代码 Attributeresult 1 public class Attributeresult { 2 String value; 3 String result; 4 5 public Attributeresult() { 6 7 } 8 9 public Attributeresult(String value, String re

java读取自定义的.properties 配置文件 中的key-value值

/** * 读取 .properties 配置文件 * @param propertiesUrl 配置文件的路径 * @return 配置文件中的key-value值 */ public static Map<String, String> getProperties(String propertiesUrl) { Map<String, String> resultMap = new HashMap<String, String>(); Properties prop

[转]java基本类型(内置类型)取值范围

原文地址:java求职重点归纳(8)--基本类型(内置类型)例作者:smallcat 例1: public class PrimitiveTypeTest { public static void main(String[] args) { // byte System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE); System.out.println("包装类:java.lang.Byte"); System.out.p

JS 遍历JSON中每个key值

JS 遍历JSON中的每个key值,可以按键值对进行存储: var myVar = { typeA: { option1: "one", option2: "two" } } Object.keys(myVar).forEach(function(k) { if(k === "typeA") { // do stuff } else if (k === "typeB") { // do more stuff } else {

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

iOS开发一些特殊的软件需要在项目中配置对应的key值,然而近期在项目中发现一个有意思的现象,苹果官方文档中提供的key值很多,但其实有一些彼此可能有冲突,当你同时配置了彼此冲突的key值,可能会出现一些奇葩的现象,而且不容易发现问题所在,下面我就我遇到的情况和大家分享一下: 因为项目需要,需要配置定位相关的key值,同时需要后台长时间运行,所以在应用中我配置了NSLocationWhenInUseUsageDescription这个定位的key值,为了在使用时获取用户的位置信息:同时我用申请了

java自定义类型 比较排序 Comparator接口

String service_time = "6:00:00,7:00:00,8:00:00,9:00:00,10:00:00,11:00:00,12:00:00,13:00:00,14:00:00,15:00:00,16:00:00,17:00:00,18:00:00,19:00:00,20:00:00,21:00:00,22:00:00 "; List<String> list = StringUtil.stringToList(service_time, "

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

1.C#代码: public bool UserAmountChange(Dictionary<string, long> fee, Dictionary<string, long> recharge) { var f = GetRechargeTypeArray(fee); var r = GetRechargeTypeArray(recharge); using (OracleConnection conn = this.CreateConnection()) using (O