Recursive generic definition and stackoverflow in Java

I am writing implementations of deterministic finite automata for some research projects, and some arcs lead to the same state

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);
    }
}

Surprisingly, if I delete one of the "addtransition" calls, there is no error

My java version is JDK 1.6 37. The operating system is Ubuntu Linux 12.04

*UPD: * stack trace is:

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)

Any comments?

Solution

After running this program, I think the problem is as follows: because you want to add a transformation from a node to yourself, you will eventually get a HashMap that maps characters to yourself When you try to add a second transformation, it needs to add the object to the HashSet The problem is that in order to do this, it needs to calculate the hash code for your object Because your object extends HashMap, it uses HashMap code to calculate the hash code of the object To this end, it attempts to recursively construct the hash code of all objects containing itself in the HashMap Therefore, it recursively attempts to calculate its own hash code, which requires it to calculate its own hash code, which requires it to calculate its own hash code, etc

I'm not sure what the best solution is, but I'll start by extending HashMap without this object It is generally considered a bad idea to use inheritance when you mean to use composition. Using HashMap as a direct field of an object means that you will break this loop, because Java will use the default implementation of hashcode, and hashcode will not attempt to calculate the depth hash code for the object

I hope this can help!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>