ArrayList 的哈希代码,它将自身包含为元素

2022-09-01 04:56:39

我们能找到包含自身的 a 吗?hashcodelistelement

我知道这是一个不好的做法,但这是面试官问的。

当我运行以下代码时,它会抛出一个:StackOverflowError

public class Main {
    public static void main(String args[]) {
        ArrayList<ArrayList> a = new ArrayList();
        a.add(a);
        a.hashCode();
    }
}

现在我有两个问题:

  1. 为什么有?StackOverflowError
  2. 是否有可能以这种方式找到哈希代码?

答案 1

用于符合实现的哈希代码已在接口中指定List

返回此列表的哈希代码值。列表的哈希代码被定义为以下计算的结果:

 int hashCode = 1;
 for (E e : list)
     hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

这确保了这意味着对于任何两个列表,并且 ,如 Object.hashCode() 的总协定所要求的。list1.equals(list2)list1.hashCode()==list2.hashCode()list1list2

这并不要求实现看起来完全像这样(请参阅如何以与 List.hashCode() 相同的方式计算流的哈希代码作为替代方案),但是对于仅包含自身的列表,正确的哈希代码将是一个必须为的数字,换句话说,不可能计算出符合要求的数字。x == 31 + xtrue


答案 2

在类中查看该方法的骨架实现。hashCodeAbstractList

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

对于列表中的每个元素,这将调用 。在您的案例中,列表本身就是唯一的元素。现在这个电话永远不会结束。该方法以递归方式调用自身,并且递归一直缠绕,直到遇到 .所以你找不到这种方式。hashCodeStackOverflowErrorhashCode