Java中的递归泛型定义和Stackoverflow

Java中的递归泛型定义和Stackoverflow,java,generics,stack-overflow,dfa,Java,Generics,Stack Overflow,Dfa,我正在为某个研究项目编写一个确定性有限自动机的实现,有一些弧导致了相同的状态。 我为州立大学写了这门课,但是 我想知道为什么代码会产生Stackoverflow: public class State extends HashMap<Character, HashSet<State>> { public static void main(String[]args) { State t=new State(); t.addTr

我正在为某个研究项目编写一个确定性有限自动机的实现,有一些弧导致了相同的状态。 我为州立大学写了这门课,但是 我想知道为什么代码会产生Stackoverflow:

 public class State extends HashMap<Character, HashSet<State>>
 {
    public static void main(String[]args)
    {
       State t=new State();
       t.addTransition('a',t);
       t.addTransition('b',t);
    }
    public void addTransition(Character symbol, State t )
    {
        if(!this.containsKey(symbol))
        {
            this.put(symbol, new HashSet<State>());
        }
        this.get(symbol).add(t);
    }
}
公共类状态扩展HashMap
{
公共静态void main(字符串[]args)
{
状态t=新状态();
t、 addTransition('a',t);
t、 addTransition('b',t);
}
公共无效添加转换(字符符号,状态t)
{
如果(!this.containsKey(符号))
{
this.put(symbol,new HashSet());
}
this.get(symbol).add(t);
}
}
令人惊讶的是,如果删除其中一个“addTransition”调用,则不会出现错误

我的Java版本是JDK1.6.37,操作系统是Ubuntu Linux 12.04

*UPD:*堆栈跟踪是:

Exception in thread "main" java.lang.StackOverflowError
at java.util.HashMap$KeyIterator.<init>(HashMap.java:843)
at java.util.HashMap$KeyIterator.<init>(HashMap.java:843)
at java.util.HashMap.newKeyIterator(HashMap.java:857)
at java.util.HashMap$KeySet.iterator(HashMap.java:891)
at java.util.HashSet.iterator(HashSet.java:170)
at java.util.AbstractSet.hashCode(AbstractSet.java:122)
at java.util.HashMap$Entry.hashCode(HashMap.java:737)
at java.util.AbstractMap.hashCode(AbstractMap.java:494)
at java.util.AbstractSet.hashCode(AbstractSet.java:126)
at java.util.HashMap$Entry.hashCode(HashMap.java:737)
at java.util.AbstractMap.hashCode(AbstractMap.java:494)
at java.util.AbstractSet.hashCode(AbstractSet.java:126)
at java.util.HashMap$Entry.hashCode(HashMap.java:737)
...
at java.util.AbstractMap.hashCode(AbstractMap.java:494)
at java.util.AbstractSet.hashCode(AbstractSet.java:126)
at java.util.HashMap$Entry.hashCode(HashMap.java:737)
at java.util.AbstractMap.hashCode(AbstractMap.java:494)
at java.util.AbstractSet.hashCode(AbstractSet.java:126)
at java.util.HashMap$Entry.hashCode(HashMap.java:737)
线程“main”java.lang.StackOverflower中出现异常 位于java.util.HashMap$KeyIterator(HashMap.java:843) 位于java.util.HashMap$KeyIterator(HashMap.java:843) 位于java.util.HashMap.newKeyIterator(HashMap.java:857) 位于java.util.HashMap$KeySet.iterator(HashMap.java:891) 在java.util.HashSet.iterator(HashSet.java:170) 位于java.util.AbstractSet.hashCode(AbstractSet.java:122) 位于java.util.HashMap$Entry.hashCode(HashMap.java:737) 位于java.util.AbstractMap.hashCode(AbstractMap.java:494) 位于java.util.AbstractSet.hashCode(AbstractSet.java:126) 位于java.util.HashMap$Entry.hashCode(HashMap.java:737) 位于java.util.AbstractMap.hashCode(AbstractMap.java:494) 位于java.util.AbstractSet.hashCode(AbstractSet.java:126) 位于java.util.HashMap$Entry.hashCode(HashMap.java:737) ... 位于java.util.AbstractMap.hashCode(AbstractMap.java:494) 位于java.util.AbstractSet.hashCode(AbstractSet.java:126) 位于java.util.HashMap$Entry.hashCode(HashMap.java:737) 位于java.util.AbstractMap.hashCode(AbstractMap.java:494) 位于java.util.AbstractSet.hashCode(AbstractSet.java:126) 位于java.util.HashMap$Entry.hashCode(HashMap.java:737)
有什么意见吗?

运行此程序后,我认为问题在于:由于要添加从节点到自身的转换,因此最终会得到一个将字符映射到自身的
HashMap
。当您尝试在第二个转换中添加时,它需要将对象添加到
哈希集中。问题是为了做到这一点,它需要为您的对象计算一个哈希代码。由于对象扩展了
HashMap
,因此它使用
HashMap
代码来计算对象的哈希代码。为此,它尝试递归地为
HashMap
中的所有对象构造哈希代码,其中包括它自己。因此,它递归地尝试计算自己的哈希代码,这要求它计算自己的哈希代码,这要求它计算自己的哈希代码,等等

我不确定这方面的最佳解决方案是什么,但我首先不让这个对象扩展
HashMap
。将
HashMap
作为对象的直接字段意味着您将打破这个循环,因为Java将使用
hashCode
的默认实现,它不会尝试为对象计算深度哈希代码


希望这有帮助

你能在问题中添加堆栈跟踪吗?我也用同样的结果进行了调试。确切的逻辑可以在AbstractMap.hashCode函数中找到。谢谢。组合方法(当HashMap是一个字段时)是有效的。我想我需要多次阅读你的评论才能理解实际发生的事情,但它似乎很有趣:)但我认为在这种特殊情况下,构图更直观。状态本身表示转换表的一部分,转换表是一个映射。有很多基于继承的实现:,)。。。无论如何,非常感谢你的帮助。