3

不変コレクションに関して一般的な質問があります。私は Java を最もよく知っているので、参考文献として使用します。

まず、不変性を保証するための一般的なアプローチはありますか? つまり、コレクション全体をコピーし、変更を加えてから、新しいオブジェクトを返す必要があるかどうかということです。より複雑で一般的なアプローチはありますか?

これをもう少し進めて、ツリーなどの「明白な」(私にとって) 可変コレクションはどうでしょうか? 通常、それらは N 個の子ノードを持つノードとして実装されます。この場合、不変性をどのように保証しますか? すべての参照を再帰的に複製およびコピーしますか?

上記に続いて、これらのコレクションへの最善のアプローチは何かと考えていました。

  1. リスト - 変更を加える前にコピーする配列ベース?
  2. キュー - フロントとバックの 2 つの配列、戻る前に複製されますか? ボードベースの実装はどうですか?
  3. ハッシュマップ - バケット配列とすべての衝突リストをコピーしますか?
  4. 設定

ご回答ありがとうございます。

4

4 に答える 4

6

幸いなことに、これの多くはすでに行われています。ImmutableCollectionImmutableListImmutableSetImmutableMapなどを含むgoogle guavaをチェックしてください。

これらのクラスのサブクラスを防止することにより (サブクラスを final にするか、コンストラクターを非公開にすることにより)、不変性が保証されます。

変更可能なコレクションから不変のコレクションを作成すると、変更可能なコレクションのデータがコピーされ、すべての変更操作が許可されなくなります-例外がスローされます(UnsupportedOperationExceptionたとえば)。

パフォーマンス上の理由から、guava ライブラリは、必要がなければデータをコピーしないように最善を尽くします。たとえば、既に がありImmutableMap、 で新しいマップを作成したImmutableMap.copyOf(theOtherImmutableMap)場合、データはコピーされません。もう一方のマップが不変であることは既にわかっているため、同じデータへの 2 つの参照があっても問題ありません。

于 2012-04-04T14:42:40.903 に答える
2

Java に関しては、Collections ユーティリティ クラスが役に立ちます。これらの操作を手動で行うのではなく、指定された API を使用することをお勧めします。特に、不変で変更不可能なメソッドに注目してください。

たとえば、不変に関しては次のとおりです。

<T> List<T>
emptyList() 
          Returns the empty list (immutable).
static
<K,V> Map<K,V>
emptyMap() 
          Returns the empty map (immutable).
static
<T> Set<T>
emptySet() 
          Returns the empty set (immutable).

変更不可の場合は次のとおりです。

static
<T> Collection<T>
unmodifiableCollection(Collection<? extends T> c) 
          Returns an unmodifiable view of the specified collection.
static
<T> List<T>
unmodifiableList(List<? extends T> list) 
          Returns an unmodifiable view of the specified list.
static
<K,V> Map<K,V>
unmodifiableMap(Map<? extends K,? extends V> m) 
          Returns an unmodifiable view of the specified map.
static
<T> Set<T>
unmodifiableSet(Set<? extends T> s) 
          Returns an unmodifiable view of the specified set.
static
<K,V> SortedMap<K,V>
unmodifiableSortedMap(SortedMap<K,? extends V> m) 
          Returns an unmodifiable view of the specified sorted map.
static
<T> SortedSet<T>
unmodifiableSortedSet(SortedSet<T> s) 

他にもいくつかの戦略があり、その下に実装できますが、私はそこから始めます.

于 2012-04-04T14:46:56.023 に答える
0

関数型言語 (haskell など) のフレームワーク内で不変コレクションがどのように機能するかを理解することを意図していると思います。すべてのコレクションが不変で最終的なものであるため、可変性、同期などに関するマルチスレッドの問題をすべて回避しながら、可変であるかのように追加、削除、および変更を行うことができます。

これについて私が見た最良の例は、Clojureのソース コードです。これは Lisp に似た言語であるため、不変のコレクションをコア機能として扱います。コレクションが clojure でどのように実装されているかを確認することを強くお勧めします。コレクションはあなたの多くの質問に答えるはずです。おそらくいくつかのことは複雑すぎるでしょう (私はまだ try をほとんど理解していません)ここを見て頑張ってください

于 2012-04-04T15:29:57.720 に答える
0

Clojure には、そのような不変 (または永続的な)コレクションが含まれています。

それはあなたが求めているすべてのコレクションを提供し、構造による突然変異をサポートします: 簡単に言えば、新しい要素を追加または削除すると新しいコレクションが返されます。これは通常 Trie 型のデータ構造を巧みに使用することで古いコレクションの大部分を再利用します。 .

これらはそのまま Java で使用するには適していません。Clojure で使用するように設計されています。

Pure4jは、これら (および Clojure が提唱する不変/値ベースのスタイル) を Java 言語に移植する試みです。それはあなたが求めているものかもしれません。

免責事項: 私は Pure4J の開発者です

于 2015-11-06T14:12:01.123 に答える