Long runtime/crash 在 hashmap 中使用 int[] 作为键时

Long runtime/crash when using int[] as key in hashmap

我正在学习动态规划的课程:https://youtu.be/oBt53YbR9Kk?t=2330 我发现出于某种原因,如果我将 HashMap 键与 int[] 一起使用,则使用较大的 m 和 n 值将花费很长时间或崩溃。如果我改用字符串形式的键,它会按预期工作。

工作代码

    public static void main(String[] args) {
        HashMap<String, Long> map = new HashMap<>();
        System.out.println(gridTraveler(18, 18, map));
    }

    /**
     * Grid Traveler problem
     * */
    public static Long gridTraveler(int m, int n, HashMap<String, Long> memo){
        String key = m + "," + n;
        if(memo.containsKey(key)){
            return memo.get(key);
        }
        if(m == 1 && n == 1) {
            return 1L;
        }
        if(m == 0 || n == 0){
            return 0L;
        }
        memo.put(key, gridTraveler(m - 1, n, memo) + gridTraveler(m, n - 1, memo));
        return memo.get(key);
    }

代码损坏

    public static void main(String[] args) {
        HashMap<int[], Long> map = new HashMap<>();
        System.out.println(gridTraveler(18, 18, map));
    }

    /**
     * Grid Traveler problem
     * */
    public static Long gridTraveler(int m, int n, HashMap<int[], Long> memo){
        int[] key = new int[]{m,n};
        if(memo.containsKey(key)){
            return memo.get(key);
        }
        if(m == 1 && n == 1) {
            return 1L;
        }
        if(m == 0 || n == 0){
            return 0L;
        }
        memo.put(key, gridTraveler(m - 1, n, memo) + gridTraveler(m, n - 1, memo));
        return memo.get(key);
    }

问题:与仅使用字符串作为键相比,为什么 int[] 键会导致我的代码崩溃?

数组不会覆盖 java.lang.Object 中的 equals()hashCode() 方法,但 java.lang.String class 会。因此,您的 Map 将一直随着新对象的增长而增长,直到由于内存限制而崩溃,即使 Map 中已经有“相等”的数组作为键。但是从java的角度来看,它们并不“相等”。

另外,你还可以使用List作为Map的key,那么不同的List对象相同的元素就被认为是相等的。

HashMap<List<Integer>, Long> 声明地图。调用 Arrays.stream(new int[]{1, 2, 3}).boxed().collect(Collectors.toList()) 将 int 数组转换为 List。

还有另一种方法,对于需要时间复制的较大数组特别有意义,将每个数组包装在一个正确实现 equalshashCode 的对象中。您可以使用 java.util.Arrays.equalsjava.util.Arrays.hashCode 作为这两种方法的核心。

同样,您可以调用 java.util.Arrays.hashCode 将每个数组转换为一个键,当两个原始数组包含相同的值时,该键将正确地“等于”另一个键。