2017-04-24 1 views
1

Listインターフェイスを使用して循環リンクリストの実装を作成しようとしていて、興味深い副作用に気づきました。循環リンクリストとイテレータAPIの確実性の欠如

CircularLinkedListはList契約を満たしていますが、 その他の現在実装されているcollectionクラスが破損しています。

公共ブールのhasNext()このリストはもし

trueを返します:反復子インタフェースはのhasNext()とhasPreviousについて次の 契約()メソッドを提供します -

問題は、これがあります が順方向にリストをたどると、イテレータの要素が増えます。 (次の例外をスローすることなく要素を返す場合は、他の言葉では、 trueを返します。)

公共ブールhasPrevious()

trueを返します。このリスト反復子がさらに要素を持っている場合 は、リストを横断するとき逆方向に。 (前の例外をスローすることなく要素を返すかどう言い換えれば、 trueを返します。)

今循環リストでは、これらのそれぞれは、必要がある契約リターン場合にのみ一覧がある場合で空です。それは各要素を追加して反復を制約する方法は使用していますのhasNext() - あなたはのaddAll()メソッドを使用して別のコレクションに適切なリスト反復子を循環リストを追加しようとする

問題は、それ自体を示し。したがって、 ループは決して終了しません!

私は現在、hasNext()メソッドを見ているか、返されるようにオーバーライドされたhasNextを持つイテレータのサブクラスを作成している場合、ListIteratorの契約を破ってリストをリンクリストのように見ていますiterator()メソッドによって呼び出されます。

つの質問:

  1. イテレータ または反復子の契約を壊すことなく、これを行うための良い方法はありますか?

  2. 誰かがこれがAbstractCollectionクラス(継承された振る舞いの由来)の欠陥であると考えていますか?コレクションの中には、追加するコレクションのtoArray()メソッドを呼び出し、配列の各要素を追加することによって、より堅牢な方法で追加を行うコレクションがあることに注意してください。私の意見で

答えて

1

これはコレクションAPIでも方法hasNexthasPrevious両方の契約が定義されている方法に問題でもありません。

問題は、あなたがあなたの循環リストについての考え方から蒸す:

  • リストは要素の固定サイズとなりイテレータ開始し、持っている方法でそれらを注文することができるはずがあり終わり。
  • hasNexthasPreviousという名前のリストに要素をどのように編成しても問題ありません。順序付けでは、返される要素がいつ定義されます。

イテレータが同じ要素(リスト内の絶対位置の点でのアイデンティティ)を返した場合、イテレータの実装は間違っています。

リストに含まれる要素の数から要素を並べる方法のアイデアを切り離さなければなりません。リスト内の要素の数は、sizeの結果によって定義されます。したがって、前方のみをナビゲートする場合、hasNexttrueと正確にはsize回で応答する必要があります。 hasNextから回答としてfalseを取得した後、逆方向にナビゲートすると、同じことがhasPreviousに当てはまります。

関連する問題