6
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

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

这是我需要澄清的几个问题

  1. 即使我将参数传递给 HashMap 的 get 方法,该参数被声明为只有 Integer 作为键,代码仍在编译。我在这里期待一个编译错误,因为我觉得这违反了严格的类型。
  2. 当我将包含错误代码的长变量作为参数传递给 HashMap() 的 get 方法时,映射返回 null。
  3. 当我将相同的 long 参数向下转换为 int 并将其传递给哈希映射的 get 方法时,映射返回正确的枚举。

我怀疑 HashMap.get() 方法中的以下行if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

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

我想了解这里的行为。

4

4 回答 4

9

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

看签名了Map.get吗?

V get(Object key)

任何对象都可以用作键。关于该设计决策还有其他 Stack Overflow 问题;稍后我会找到一个。

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

是的,它会 - 因为它将被装箱到 a Long,并且 aLong不等于 a Integer。因此在地图中找不到该条目。

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

是的,它会 - 因为那样它将被装箱到一个Integer,这将等于适当的键。

基本上你被你可以比较intlong值的事实所愚弄——这只是编译器自动为你提升intlong;如果您将IntegerandLong视为完全独立的类型,并且它们之间没有自动转换,那么您的地图行为非常有意义。

于 2013-02-05T08:20:49.630 回答
1

1.) 即使我将一个 long 参数传递给 HashMap 的 get 方法,该方法被声明为只有 Integer 作为键,代码仍在编译。我在这里期待一个编译错误,因为我觉得这违反了严格的类型。

这里没有编译错误:具有由泛型类型限制的参数的 Map 的唯一方法是put方法。getcontainsKey接受一个Object.

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

当你调用get(param)它时,它会被翻译成get(new Long(param)). 所以参数永远不会等于Integer

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

当你调用get((int)param)它时,它会被翻译成get(new Integer((int)param)). 所以参数类型现在是正确的,结果就是你所期望的。

于 2013-02-05T08:30:23.670 回答
0

您需要将 long 转换为 int。

于 2013-02-05T08:22:58.170 回答
0

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

要详细说明该答案:

由于自动装箱,您的 long 将被转换为 Long,然后将与 Map 中具有相同 hashCode 的任何其他对象进行比较。由于 HashCode 的具体实现不能与 Long 和 Integer 相等,这可能已经失败。如果 hashCodes 是相同的,尽管要进行 equals 检查,这将失败,因为就像每个 equals 方法一样,检查“是 [Type] 的实例”或返回 false。在将 Long 与 Integer 进行比较的每种情况下,这都会失败。

因此,在您的情况下,您需要做的就是将 long 转换为 int 或执行 Integer.valueOf((int)param) ,这将完全一样(自动装箱)。

于 2013-02-05T08:29:52.863 回答