214

Stackユースケースにはデータ構造が必要です。アイテムをデータ構造にプッシュできる必要があり、スタックから最後のアイテムのみを取得したい。スタックのJavaDocは次のように述べています。

Deque インターフェイスとその実装によって、より完全で一貫性のある LIFO スタック操作のセットが提供されます。これは、このクラスより優先して使用する必要があります。例えば:

Deque<Integer> stack = new ArrayDeque<>();

メソッドに対してローカルなこのデータ構造を使用するため、ここでは同期動作は絶対に望んでいません。これとは別に、なぜここを好む必要があるDequeStackですか?

PS: Deque の javadoc には次のように書かれています。

Deques は LIFO (Last-In-First-Out) スタックとしても使用できます。このインターフェイスは、従来の Stack クラスよりも優先して使用する必要があります。

4

6 に答える 6

252

一つには、それは継承の観点からより賢明です。Stack私の見解では、拡張するという事実Vectorは本当に奇妙です。Javaの初期には、継承はIMOを使いすぎPropertiesていました。これは別の例です。

私にとって、あなたが引用したドキュメントの重要な言葉は一貫しています。Dequeコレクションの最初または最後からアイテムをフェッチ/追加/削除したり、反復したりすることができる一連の操作を公開します。これで完了です。位置によって要素にアクセスする方法は意図的にありません。これは、のサブクラスであるためStackに公開されます。Vector

ああ、またStackインターフェースがないので、操作が必要であることがわかっている場合はStack、特定の具象クラスにコミットすることになります。これは通常、良い考えではありません。

また、コメントで指摘されているように、Stack逆のDeque反復順序があります。

Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(new ArrayList<>(stack)); // prints 1, 2, 3


Deque<Integer> deque = new ArrayDeque<>();
deque.push(1);
deque.push(2);
deque.push(3);
System.out.println(new ArrayList<>(deque)); // prints 3, 2, 1

これは、JavaDocs for Deque.iterator()でも説明されています。

この両端キューの要素に対して適切な順序でイテレータを返します。要素は、最初(ヘッド)から最後(テール)の順に返されます。

于 2012-09-21T05:49:35.020 に答える
5

これは、Stack クラスの説明で言及されている矛盾の私の解釈です。

ここで汎用実装を見ると、セット、マップ、およびリストの実装に一貫したアプローチがあることがわかります。

  • セットとマップには、ハッシュ マップとツリーを使用した 2 つの標準実装があります。最初のものは最もよく使用され、2 番目のものは順序付けられた構造が必要な場合に使用されます (また、独自のインターフェース (SortedSet または SortedMap) も実装します)。

  • Set<String> set = new HashSet<String>();see reason hereのように、推奨される宣言スタイルを使用できます。

ただし、Stack クラス: 1) 独自のインターフェイスがありません。2) サイズ変更可能な配列に基づく Vector クラスのサブクラスです。では、スタックの連結リストの実装はどこにあるのでしょうか?

Deque インターフェイスでは、2 つの実装 (サイズ変更可能な配列 - ArrayDeque、リンク リスト - LinkedList) を含め、このような問題はありません。

于 2014-04-14T14:11:30.053 に答える