2016-06-24 11 views
-1

以下の2つの実装を検討すると、最初の実装は実際にどのように使用されますか?私は記事で読んだものから、具体的なクラスとのインタフェース

List<String> a= new ArrayList<String>(); 
ArrayList<String> b= new ArrayList<String>(); 

、我々は

a=new TreeList<String>(); 

として再実装を変更することができますように最初の実装は、破壊の変化を回避するのに役立ちます。しかし、私はいただきましたが、実際の使用を理解していませんListインターフェイスのメソッドだけを使用できるので、実装をtreelistで変更しますか?

+3

"ソート"を考えてください。 ArrayListは 'add'でソートされません。他の実装もそうするかもしれない。したがって、要件がソートされたアイテムに変更された場合は、実装を交換するだけで済みます。クライアントコードの実装を変更することなくクライアントコードの動作を変更しました(実装を選択する行は1行を除く)。もちろん:特定の実装に固有のメソッドを使用する必要がある場合、その実装にバインドされています。 – Fildor

答えて

2

しかし、私はListインターフェイスメソッドだけを使用できるので、treelistを使って実装を変更するのはどういうことを理解していませんか?

インタフェースListの異なる実装は、異なる動作に対して異なる性能特性を有する。 Listのどの実装を選択すべきかは恣意的ではありません。異なる実装は、異なる目的に対してより効率的です。

たとえば、中間のどこかに要素を挿入すると、ArrayListでは高価になりますが、実装が機能するため、LinkedListで安くなります。同様に、インデックスによる要素へのアクセスは、ArrayListでは安いが、LinkedListでは高価である。

プログラムの作成を開始したときに、あまり考えずにArrayListを使用したが、後でLinkedListが効率的であることがわかりました。あなたがインターフェイスListの代わりに、特定の実装に対してプログラムされてきた

は、それがArrayListからLinkedListに変更することは非常に簡単です - あなただけに持っていると思いますので、プログラムの残りの部分に、それはまだ、Listのように見えます1行を変更します。

+0

ありがとうございました..今すぐ理解しました – Zephyr

1

TreeListが存在しないので、例としてPersistentListを使用してください。

あなたは、データベースに保存したい@Entityを考えてみましょう:今すぐ

public class MyMagicEntity { 
    @OneToMany 
    List<MyChildEntity> children; 

    public void setChildren(final List<MyChildEntity> children) { 
     this.children = children; 
    } 
} 

、あなたがMyMagicEntityを作成する際には、

final MyMagicEntity mme = new MyMagicEntity(); 
final List<MyChildEntity> children = new ArrayList<>(); 
children.add(new MyChildEntity("one")); 
children.add(new MyChildEntity("two")); 
children.add(new MyChildEntity("three")); 
mme.setChildren(children); 

//save to DB 

ような何かをするだろうですから、ArrayListを作成MyMagicEntityに渡され、Listに割り当てられます。Listと同じ長さの実装であることには気を付けません。

は今、後であなたは:

final MyMagicEntity mme = //load from DB 
final List<Children> children = mme.getChildren(); 

だから、children何ですか?さて、JPAとHibernateを使用しているのであれば、実際にはPersistentListであり、ArrayListではありません。

私たちがchildrenのメンバーにアクセスすると、Hibernateはデータベースからそれらを引き出します。このListはまだListです。あなたのプログラムはこれを知る必要はありません。

Listインターフェイスを使用せずにこれを実行できますか?いいえ!ので:

  • は、あなたがこのListの根本的な振る舞いは完全に異なっている極端な例、であるがPersistentList
  • HibernateはArrayList

を作成することはできません作成することはできません、これはすべての種類に適用されます他の状況の。

例えば

  • ArrayListLinkedListが、あなたは
  • グアバを切り替えたいことがあり、異なる性能特性を持っているあなたが使用することをお勧めしますImmutableList持ってしたいことがあり
  • Collections.unmodifyableListimplements List、使用する
  • Listは、ファイル
  • でバックアップされている可能性があります

基本的な考えは、Listはどのようなリストでもできなければならないことを定義していますが、その仕組みは定義していません。

+0

回答ありがとうございました – Zephyr

0

ここでListは、Listで実行できるすべての一般的な操作方法を含むインターフェイスです。

ListインターフェイスはArrayListLinkedListと多くのクラスの親です。したがって、これらのタイプのオブジェクト参照はすべて保持できます。

これらのすべてのListメソッドは、異なるクラス(または独自のタイプ)の実装を持っています。したがって、どのメソッドを使用しても、クラスに属するObjectのオーバーライドメソッドの定義に従って自動的に適用されます。

List<String> a= new ArrayList<String>(); 
ArrayList<String> b= new ArrayList<String>(); 

ここで、どちらの方法も問題ないと宣言できます。このようなシナリオを考えてみましょう。

あなたはいくつかのサービスを呼び出しており、そのうちのどれかList(特定ではない)を返すことを知っています。 LinkedListまたはArrayList、または他のタイプのリストでも構いません。

あなたが得た応答はどれですか?Listリファレンス変数のタイプでこれらの応答を簡単に保持できます。

となり、結果を収集した後、オブジェクトタイプをさらに区別できます。

1

あなた自身のより効率的なリスト実装を開発することに決めたと言います。おそらく、内部的にメモリ管理が優れているか、より高速な設定メソッド(挿入)実装である可能性があります。 Listインターフェイスを実装するだけで、残りのコードはこの1行を除いて変更なしで引き続き動作します。 ArrayListを拡張して独自のコードを記述することもできます。

//Old code 
List<String> a = new ArrayList<String>(); 
a.set(0, "Test"); 

//New code 
List<String> a = new MyCustomisedList<String>(); 
//Same code, but your optimized set logic. May be faster... 
a.set(0, "Test"); 
+0

良い例... – Zephyr

関連する問題