7

私はいくつかの研究プロジェクトのために決定論的有限オートマトンの実装を書いていますが、同じ状態につながるアークがいくつかあります。私は 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」呼び出しの 1 つを削除してもエラーは発生しません。

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)

コメントはありますか?

4

1 に答える 1

11

このプログラムを実行した結果、問題は次のようになると思います。ノードからそれ自体への遷移を追加しているためHashMap、文字をそれ自体にマップする になります。2 番目のトランジションに追加しようとすると、オブジェクトを に追加する必要がありますHashSet。問題は、これを行うために、オブジェクトのハッシュ コードを計算する必要があることです。オブジェクトが extendsHashMapであるため、コードを使用しHashMapてオブジェクトのハッシュ コードを計算します。HashMapこれを行うために、それ自体を含む内のすべてのオブジェクトのハッシュ コードを再帰的に構築しようとします。したがって、再帰的に独自のハッシュコードを計算しようとします。これには、独自のハッシュコードを計算する必要があり、独自のハッシュコードを計算する必要があります。

これに対する最善の修正が何であるかはわかりませんが、このオブジェクトを extends しないことから始めますHashMap一般に、合成を使用する場合に継承を使用するのは悪い考えと考えられていますHashMapオブジェクトの直接フィールドを作成するということは、Java がオブジェクトのディープ ハッシュ コードを計算しようとしない のデフォルトの実装を使用するため、このサイクルを断ち切ることを意味しますhashCode

お役に立てれば!

于 2012-11-30T06:44:38.520 に答える