You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java自定义HashMap相等判断函数失效问题排查

自定义HashMap相等判断函数的问题分析

问题场景

尝试用自定义的matches函数判断两个HashMap是否相等,预期输出true,但实际输出false。以下是代码及运行结果:

代码片段

import java.util.HashMap;

public class HashMapEquals{

    private static boolean matches1(HashMap<Character, Integer> one, HashMap<Character, Integer> two){
        for(char c: one.keySet()){
            if(one.get(c) != two.get(c))
                return false;
        }
        return true;
    }

    private static boolean matches2(HashMap<Character, Integer> one, HashMap<Character, Integer> two){
        for(char c: two.keySet()){
            if(two.get(c) != one.get(c))
                return false;
        }
        return true;
    }

    private static boolean matches(HashMap<Character, Integer> one, HashMap<Character, Integer> two){
        boolean first = matches1(one, two);
        boolean second = matches2(one, two);
        System.out.println(first);
        System.out.println(second);
        return (first && second);
    }

    public static void main(String args[]){
        HashMap<Character, Integer> one = new HashMap<>();
        HashMap<Character, Integer> two = new HashMap<>();

        one.put('a', 10000);
        two.put('a', 10000);

        matches(one, two);
        System.out.println(one.equals(two));
    }
}

运行输出

$ java HashMapEquals
  false
  false
  true

问题原因

核心问题出在用!=比较Integer对象:

  • Integer是引用类型,!=比较的是对象的内存地址(引用),而非实际数值。
  • 对于值在-128~127范围内的Integer,Java会从常量池复用对象,此时!=能碰巧比较值相等;但当值超出这个范围时(比如代码中的10000),Java会创建新的Integer对象,此时两个值相同的Integer对象引用不同,!=返回true,导致matches1和matches2直接返回false。

而HashMap内置的equals()方法会正确遍历每个键值对,用equals()方法比较值的内容而非引用,所以能得到正确结果。

修复方案

把引用比较!=改成用equals()比较值内容,同时可以用Objects.equals()简化null值处理(避免空指针异常),还可以先判断两个HashMap的size是否相等,快速排除键数量不同的情况:

修复后的代码示例

import java.util.HashMap;
import java.util.Objects;

public class HashMapEquals{

    private static boolean matches1(HashMap<Character, Integer> one, HashMap<Character, Integer> two){
        for(char c: one.keySet()){
            if(!two.containsKey(c) || !Objects.equals(one.get(c), two.get(c))){
                return false;
            }
        }
        return true;
    }

    private static boolean matches2(HashMap<Character, Integer> one, HashMap<Character, Integer> two){
        for(char c: two.keySet()){
            if(!one.containsKey(c) || !Objects.equals(two.get(c), one.get(c))){
                return false;
            }
        }
        return true;
    }

    private static boolean matches(HashMap<Character, Integer> one, HashMap<Character, Integer> two){
        // 先判断size,快速排除不相等情况
        if(one.size() != two.size()){
            return false;
        }
        boolean first = matches1(one, two);
        boolean second = matches2(one, two);
        System.out.println(first);
        System.out.println(second);
        return (first && second);
    }

    public static void main(String args[]){
        HashMap<Character, Integer> one = new HashMap<>();
        HashMap<Character, Integer> two = new HashMap<>();

        one.put('a', 10000);
        two.put('a', 10000);

        System.out.println(matches(one, two));
        System.out.println(one.equals(two));
    }
}

内容的提问来源于stack exchange,提问作者Sai Pavan Kalyan Munaga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:45:23