Java 将long值传递给get方法时,键为integer的Map返回null

Java 将long值传递给get方法时,键为integer的Map返回null,java,collections,Java,Collections,================================================================================= 这里有几个问题我需要澄清 即使我将long作为参数传递给 HashMap,声明只有整数作为键。我希望这里会出现编译错误,因为我觉得这违反了严格的类型 当我将包含错误代码的长变量作为参数传递给get HashMap()的方法,该映射返回null 当我将同一个long参数向下转换为int并将其传递给哈希映射的get方法时,映射返回正确的枚

=================================================================================

这里有几个问题我需要澄清

  • 即使我将long作为参数传递给 HashMap,声明只有整数作为键。我希望这里会出现编译错误,因为我觉得这违反了严格的类型
  • 当我将包含错误代码的长变量作为参数传递给get HashMap()的方法,该映射返回null
  • 当我将同一个long参数向下转换为int并将其传递给哈希映射的get方法时,映射返回正确的枚举
  • 我怀疑HashMap.get()方法
    if(e.hash==hash&&((k=e.key)==key | | key.equals(k))

    我不确定int==long是否会失败,或者它们对应的包装器是否会失败。我甚至在main方法中添加了一个检查来验证int和long变量的相等性

    我想了解这里的行为

    即使我将long作为参数传递给HashMap的get方法,该方法被声明为只有Integer作为键,代码仍在编译。我希望这里会出现编译错误,因为我觉得这违反了严格的类型

    你看了我的签名了吗

    任何对象都可以用作键。关于该设计决策还有其他堆栈溢出问题;我等会儿再找

    当我将包含错误代码的长变量作为参数传递给HashMap()的get方法时,map返回null

    是的,它会-因为它将被装箱为
    Long
    ,而
    Long
    不等于
    整数。因此在地图中找不到该条目

    当我将同一个long参数向下转换为int并将其传递给哈希映射的get方法时,映射返回正确的枚举

    是的,它会-因为这样它将被装箱为一个
    整数
    ,该整数将等于相应的键


    基本上,你被这样一个事实愚弄了:你可以比较
    int
    long
    值——这只是编译器自动将
    int
    提升到
    long
    ;如果您认为
    Integer
    Long
    是完全独立的类型,它们之间没有自动转换,那么映射的行为是完全合理的。

    您需要将Long转换为int。

    简单的答案是:Integer==Long将始终无法等于([Long].equal([Integer])==false)Long.hashCode()==Integer.hashCode()也可能返回相同的结果

    要详细说明这一答案:

    由于自动装箱,您的long将被转换为long,然后与映射中具有相同哈希代码的任何其他对象进行比较。由于HashCode的具体实现对于Long&Integer不能相等,因此可能已经失败了。如果hashCodes是相同的,但需要执行equals检查,这将失败,因为与所有equals方法一样,它会检查“is instance of[Type]”或返回false。在每次比较Long和整数时都会失败

    因此,在本例中,您需要做的就是将long强制转换为int或do Integer.valueOf((int)param),它将执行完全相同的操作(自动装箱)

    1.)即使我将long作为参数传递给HashMap的get方法,该方法声明为只有整数,代码仍在编译 就像钥匙一样。我以为这里会有编译错误,因为我 不知怎的,我觉得这违反了严格的打字规则

    这里没有编译错误:Map的唯一方法是
    put
    方法,其参数由泛型类型限定
    get
    containsKey
    接受
    对象

    2.)当我将包含错误代码的长变量作为参数传递给HashMap()的get方法时,map返回null

    调用
    get(param)
    时,它将被转换为
    get(new Long(param))
    。 因此参数永远不等于
    整数

    3.)当我将相同的long参数向下转换为int并将其传递给哈希映射的get方法时,映射返回正确的枚举

    调用
    get((int)param)
    时,它将被转换为
    get(newinteger((int)param))

    因此,参数类型现在是正确的,结果是您所期望的。

    欢迎使用堆栈溢出!当你问你的问题时,有一个方便的方法,如何将方框格式化到右边。值得一读。还有一个预览区,你可以在这里输入问题,在发布前检查结果,这总是值得一看的。这一次我为您做了一些基本的格式化。谢谢Jon,我参考了另一个堆栈溢出问题来了解为什么映射没有完全通用。我忘了查看签名,我假设get(K键)并开始查看代码。
    import java.util.HashMap;
    import java.util.Map;
    
    public class StackOverFlowQuestion {
    
    private static final int ERROR_CODE100 = -100;
    private static final int ERROR_CODE101 = -101;
    private static final int ERROR_CODE102 = -102;
    private static final int ERROR_CODE103 = -103;
    private static final int ERROR_CODE104 = -104;
    
    public enum ErrorDetails {
    
        ERROR_CODE_100(ERROR_CODE100, "Error code 100 Desc", false),
    
        ERROR_CODE_101(ERROR_CODE101, "Error code 101 Desc", false),
    
        ERROR_CODE_102(ERROR_CODE102, "Error code 102 Desc", true),
    
        ERROR_CODE_103(ERROR_CODE103, "Error code 103 Desc", false),
    
        ERROR_CODE_104(ERROR_CODE104, "Error code 104 Desc", true);
    
        private int errorCode;
        private String errorMsg;
        private boolean canRetry;
    
        private ErrorDetails(int errorCode, String errorMsg, boolean canRetry) {
            this.errorCode = errorCode;
            this.errorMsg = errorMsg;
            this.canRetry = canRetry;
        }
    
        public String getErrorMsg() {
            return this.errorMsg;
        }
    
        public boolean canRetry() {
            return this.canRetry;
        }
    
        public String toString() {
            return "Error code : " + errorCode + ", errorMsg : " + errorMsg
                    + ", canRetry : " + canRetry;
        }
    }
    
    private Map<Integer, ErrorDetails> errorMap;
    
    public StackOverFlowQuestion() {
        System.out.println("StackOverFlowQuestion.StackOverFlowQuestion()");
    
        errorMap = new HashMap<Integer, StackOverFlowQuestion.ErrorDetails>();
    
        errorMap.put(ERROR_CODE100, ErrorDetails.ERROR_CODE_100);
        errorMap.put(ERROR_CODE101, ErrorDetails.ERROR_CODE_101);
        errorMap.put(ERROR_CODE102, ErrorDetails.ERROR_CODE_102);
        errorMap.put(ERROR_CODE103, ErrorDetails.ERROR_CODE_103);
        errorMap.put(ERROR_CODE104, ErrorDetails.ERROR_CODE_104);
    
        System.out.println("errorMap : " + errorMap);
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        long param = -100;
        StackOverFlowQuestion question = new StackOverFlowQuestion();
        System.out.println("question.errorMap : " + question.errorMap);
    
        System.out.println("question.errorMap.containskey(param) : "
                + question.errorMap.containsKey(param));
        ErrorDetails errorDetails = question.errorMap.get(param);
        System.out.println("errorDetails : " + errorDetails);
    
        System.out.println("question.errorMap.containskey((int)param) : "
                + question.errorMap.containsKey((int) param));
        ErrorDetails errorDetailsWithInt = question.errorMap.get((int) param);
        System.out.println("errorDetailsWithInt : " + errorDetailsWithInt);
    
                int paramInt = -100;
        System.out.println("param == paramInt : " + (param == paramInt));
    }
    
    StackOverFlowQuestion.StackOverFlowQuestion()
    
    errorMap : {-100=Error code : -100, errorMsg : Error code 100 Desc, canRetry : false, -102=Error code : -102, errorMsg : Error code 102 Desc, canRetry : true, -101=Error code : -101, errorMsg : Error code 101 Desc, canRetry : false, -104=Error code : -104, errorMsg : Error code 104 Desc, canRetry : true, -103=Error code : -103, errorMsg : Error code 103 Desc, canRetry : false}
    
    question.errorMap : {-100=Error code : -100, errorMsg : Error code 100 Desc, canRetry : false, -102=Error code : -102, errorMsg : Error code 102 Desc, canRetry : true, -101=Error code : -101, errorMsg : Error code 101 Desc, canRetry : false, -104=Error code : -104, errorMsg : Error code 104 Desc, canRetry : true, -103=Error code : -103, errorMsg : Error code 103 Desc, canRetry : false}
    
    question.errorMap.containskey(param) : false
    errorDetails : null
    
    question.errorMap.containskey((int)param) : true
    errorDetailsWithInt : Error code : -100, errorMsg : Error code 100 Desc, canRetry : false
    
    param == paramInt : true
    
    V get(Object key)