1

Listへの呼び出しによって取得されたサブリストのメソッドを介してa が構造的に変更された場合、インデックスおよびインデックスとリスト要素間の関係はどうなりList.subList(int fromIndex, int toIndex)ますか?

たとえば、Oracle JVM で見られるような事実上の操作には興味がありません。私はインターフェイスの動作仕様に興味があるので、独自のリスト クラスを確実に実装できます (ここでの信頼性とは、Java のリスト クラスの 1 つを独自のものと交換できることを指します。これは、java.util.Listインターフェイスを実装するという唯一の利点によるものです)。

オラクルによるドキュメントはList、上記を明らかにしていないようです。注意してください、これは sub-list 以外の方法でリストを変更しようとすることとは何の関係もありません。実際にドキュメントでサポートされているように、これは sub-list onlyによる変更に関するものです。

例:

6 つの要素のリストがあるとしますA, B, C, D, E, F。リストを呼び出すと、要素B、C、DsubList(1, 4)を持つサブリストが生成されます。次に、このサブリストを呼び出します。が削除された後にサブリストに含まれる要素を知りたいですか? いくつかの代替案:remove(D)D

  1. B、C、E (サブリストは元のインデックス範囲を保持)?
  2. B、C (事実上、もはや a ではありませんsubList(1, 4))?

私の推測では、サブリストが指定されたsubList(1, 4)ので、リスト自体の「ウィンドウ」は同じ「サイズ」でなければならEず、ビューの終了インデックスがまだ 4 であるため、いわばビューにスライドします。今でDはなくなってすぐに伸びていますE。2 番目の選択肢は、私にはあまり賢明ではないように思えますが、それでも代替案です。

4

4 に答える 4

4

質問に答えるかもしれない次の引用された仕様は、 classのドキュメントでjava.util.AbstractList見つかりました(そして少し驚くべきことに、のドキュメントではありませんjava.util.List):

この実装は、AbstractList をサブクラス化するリストを返します。サブクラスは、プライベート フィールドに、バッキング リスト内の subList のオフセット、subList のサイズ(存続期間中に変化する可能性があります)、およびバッキング リストの予想される modCount 値を格納します。

ビューのサイズが変更される可能性があるという事実から、インデックスも変更される可能性があるということになります。つまり、質問で概説されているシナリオ例では、要素Eは「ビューにスライド」しません。削除後のサブリストのサイズはD1 減り、その時点でのサブリストには 2 つの要素が含まれているため、2 番目の選択肢は正しいB, Cです。

-のドキュメントページではなく、ページで上記を指定することは、Java 設計者の意図的な選択である可能性があります。ただし、実装する 2 つの異なるリスト クラスは、この特定の詳細レベルで簡単に交換でき、互換性があると思います。また、すべての実装が拡張されるわけではありません。これは便利であり、要件ではありません。AbstractListListListListAbstractList

これは、引用された仕様を(他の詳細とともに)AbstractListページからListドキュメントページに移動することです。

于 2013-03-10T15:47:09.880 に答える
2

サブリストは であるためList、要素を削除するには、そのサイズを縮小する必要があります。さらに、要素はバッキング リストからも削除する必要があります。(Javadoc には次のように書かれています。

返されるリストは、このリストによって裏付けられています

返されたリストは、このリストでサポートされているすべてのオプションのリスト操作をサポートしています。

于 2013-06-23T10:41:07.973 に答える
1

List インターフェイスはコントラクトであり、異なる実装は、コントラクトで指定されていないものに対して好きなことを自由に行うことができます。

要約すると、「このリストのxyの間の部分のビュー」という句の「静的」または「動的」な解釈があるかどうかにかかっています。これはsubList、バッキング リストのxyの間の部分のビューですサブリストが作成されたとき(静的)またはサブリストの各操作が実行されたとき(動的)?どちらの読み方もコントラクトに従って受け入れられ、異なる実装ではどちらでも自由に行うことができます。

remove特に、削除後はリストを以前よりも小さくする必要があるという契約には何もありません。これは、マルチスレッドまたはイベントリスナーが存在する場合に聞こえるほど奇妙な状況ではありません。みたいなケース

// lst contains B, C, D
lst.remove(D);
// lst contains B, C, E

ダイナミックの結果である可能性があり、subListE をリストに追加する別のスレッドである可能性があります。または、要素の削除時にイベントを発生させ、イベント リスナーが E を追加したリストの実装である可能性があります。

于 2013-06-23T11:00:44.710 に答える