簡體   English   中英

Java中的遞歸泛型定義和Stackoverflow

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM