[英]Recursive generic definitions and Stackoverflow in Java
我正在為一些研究項目編寫確定性有限自動機的實現,並且有一些弧導致相同的狀態。 我為State編寫了這個類,但我想知道為什么代碼會產生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);
}
}
令人驚訝的是,如果我刪除其中一個“addTransition”調用,則沒有錯誤。
我的Java版本是JDK 1.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)
任何意見?
運行此程序后,我認為問題如下:由於您要添加從節點到自身的轉換,因此您最終會得到一個將字符映射到自身的HashMap
。 當您嘗試添加第二個轉換時,它需要將對象添加到HashSet
。 問題是,為了做到這一點,它需要為您的對象計算哈希碼。 由於您的對象擴展了HashMap
,它使用HashMap
代碼來計算對象的哈希代碼。 為此,它嘗試遞歸地構造HashMap
中包含自身的所有對象的哈希代碼。 因此,它遞歸地嘗試計算自己的哈希碼,這需要它計算自己的哈希碼,這需要它計算自己的哈希碼等。
我不確定這是什么最好的解決方案,但我會從沒有這個對象擴展HashMap
。 當你意味着使用組合時,通常認為使用繼承是一個壞主意 。 使HashMap
成為對象的直接字段意味着您將打破此循環,因為Java將使用hashCode
的默認實現,而hashCode
不會嘗試為對象計算深度哈希代碼。
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.