さて、SortedMap/SortedSetはインターフェースであり、TreeMap/TreeSetは実装です。どちらも要素をソートされた順序で保持していますよね?では、なぜTreeMap/が必要なのTreeSetですか?
5 に答える
インターフェイスは機能を提供しません。提供するメソッドの観点からクラスの一般的なアウトラインを定義するだけです。SortedMapしかし、 /の中SortedSetには、この機能を実際に実現する方法を実装するコードはありません。
実際のところ、同じ機能を実現する方法は複数あることがよくあります。インターフェースについて考えてみてください。それをとしてだけでなく、java.util.Setとして実装することもできます。通常、異なる実装の間にはいくつかのトレードオフがあります。ハッシュセットは平均してより速いアクセス時間を提供する可能性がありますが、ツリーセットはそのアイテムの順序を維持するのに優れている可能性があります。TreeSetHashSet
ただし、多くの場合、開発者は、アイテムをセットに格納して取得できることを知っている限り、実装の詳細を気にしません。その基本的な考え方は、それを実現する方法ではなく、インターフェースによって定義されます。
これは、インターフェイスをインスタンス化できない理由でもあります。次のことを試してみてください。
SortedSet<Integer> set = new SortedSet<Integer>();
あなたのコンパイラは文句を言うでしょう。これは、「SortedSet」が実際にはセット自体を認識しないため、ソートされたセットの実装がメソッドに関して提供する必要があるものを定義するだけだからです。
これが不自然な例です。セット内の正の整数のパーセンテージを計算する機能を提供したいとします。メソッドを定義できます。
public double getPercentageOfPositives(Set<Integer> set) {
if (set.size() == 0) {
return 0.0;
}
int count = 0;
for (Iterator<Integer> iter = set.iterator(); iter.hasNext();) {
if (iter.next() > 0) count++;
}
return 100.0 * count / set.size();
}
ここでは、メソッドのユーザーがあなたにaを与えるか。を与えるかは実際には気にしませTreeSetんHashSet。size()とにかくメソッドとメソッドを呼び出すだけなので、特定のクラスがどの原則を使用するかは問題ではありませiterator()ん。必要なのは、どのセットにもこれら2つの方法があるという事実を信頼することだけです。インターフェースはあなたにその信頼を与えます。
したがって、メソッドシグネチャは、を要求するだけですSet。これは、それを実装するすべてのクラスが(とりわけ)asize()とiterator()メソッドを提供する必要があることを定義するインターフェイスです。このように書いた場合:
public double getPercentageOfPositives(SortedSet<Integer> set) {
...
}
そして、私はそのインスタンスを持っていますが、提供しているにHashSetもかかわらず、あなたのメソッドを使用できませんでした。:-(HashSetsize()iterator()
その意味で、インターフェースはスーパークラスのようなものであり、それを実装するためにすべてのクラスが持つ必要のある共通性を定義します。ただし、それ自体は機能を提供しません。
したがって、元の例に戻ると、SortedSetこのインターフェイスは機能を提供しません。ソートされたセットの実装が提供する必要のあるメソッドを定義するだけです。TreeSetそのような実装です。
同じ考え方がに当てはまりますSortedMap。
クラスがあるときにインターフェースが必要だからです。
SortedMapとでSortedSetツリーを使用して実装される機能を定義しTreeMapますTreeSet。
SortedMap/SortedSetはインターフェースであるため、インスタンス化することはできません。 TreeMap/TreeSetはクラスであり、インスタンス化して使用できます。SortedMap/が必要な理由はSortedSet、Sunのツリーベースの実装以外の実装が存在する可能性があるためです。
これが全体像を把握するためのチートシートです(ソースは画像にあります)

答えはあなたの質問にあります。SortedMapおよびSortedSetはインターフェースです。これらはメソッドとプロパティを定義しますが、実際にはそれらを実装していないため、機能を提供しません。
TreeMapおよびTreeSetは、これらのインターフェースの実装です。
優れたOOP設計手法では、実装ではなくインターフェイスにコーディングすることをお勧めします。つまり、すべてのメソッドシグネチャは、クラスではなくインターフェイスを参照する必要があります。
だからあなたはするでしょう:
Object squishObjects(SortedMap map);
それ以外の
オブジェクトsquishObjects(TreeMapマップ);
そうすれば、のより良い実装が実現した場合、SortedMapに依存していたすべてのメソッドを変更することなく、それを切り替えることができますTreeMap。