Javaチームは、Java 8の関数型プログラミングの障壁を取り除くために多大な努力をしてきました。特に、java.utilコレクションの変更は、変換を非常に高速なストリーム操作に連鎖させるという素晴らしい仕事をしています。彼らがコレクションにファーストクラスの関数と機能メソッドを追加するのをどれだけうまくやったかを考えると、なぜ彼らは不変のコレクションや不変のコレクションのインターフェースを提供することに完全に失敗したのでしょうか?
既存のコードを変更せずに、Javaチームはいつでも変更可能なインターフェイスと同じ不変インターフェイスを追加し、「set」メソッドを削除して、既存のインターフェイスを次のように拡張できます。
ImmutableIterable
____________/ |
/ |
Iterable ImmutableCollection
| _______/ / \ \___________
| / / \ \
Collection ImmutableList ImmutableSet ImmutableMap ...
\ \ \_________|______________|__________ |
\ \___________|____________ | \ |
\___________ | \ | \ |
List Set Map ...
確かに、List.add()やMap.put()などの操作は現在、指定されたキーのブール値または前の値を返し、操作が成功したか失敗したかを示します。不変のコレクションは、そのようなメソッドをファクトリーとして扱い、追加された要素を含む新しいコレクションを返す必要があります-これは現在の署名と互換性がありません。ただし、ImmutableList.append()または.addAt()およびImmutableMap.putEntry()などの別のメソッド名を使用することで回避できます。結果として得られる冗長性は、不変のコレクションを操作する利点よりも重要であり、型システムは間違ったメソッドを呼び出すエラーを防ぎます。時間が経つにつれて、古いメソッドは廃止される可能性があります。
不変コレクションの勝利:
- シンプルさ-基礎となるデータが変更されない場合、コードについての推論は簡単です。
- ドキュメンテーション-メソッドが不変のコレクションインターフェイスを取る場合、そのコレクションを変更しないことを知っています。メソッドが不変のコレクションを返す場合、変更できないことを知っています。
- 並行性-不変コレクションはスレッド間で安全に共有できます。
不変性を前提とする言語を味わった人として、Wild延する突然変異のワイルドウエストに戻ることは非常に困難です。Clojureのコレクション(シーケンス抽象化)には、Java 8コレクションが提供するすべてのものと、不変性(ストリームの代わりに同期されたリンクリストのために余分なメモリと時間を使用する可能性があります)が既にあります。Scalaには、操作の完全なセットを備えた可変コレクションと不変コレクションの両方があり、それらの操作は熱心ですが、.iteratorを呼び出すと遅延ビューが得られます(また、それらを遅延評価する他の方法があります)。不変のコレクションがなければ、Javaがどのように競争し続けることができるかわかりません。
誰かがこれに関する歴史や議論を教えてくれますか?確かにどこかで公開されています。
const
コレクション
Collections.unmodifiable*()
は防御的なコピーであり、その目的です。しかし、これらが不変の場合は不変として扱わないでください
ImmutableList
その図に含まれている場合、人々は可変で渡すことができList
ますか?いいえ、それはLSPの非常に悪い違反です。