2011-08-12 4 views
2

JavaのStringクラスのように、インターンをサポートするクラスが必要です。クラスのインスタンスを作成するときに、同じパラメータを持つ参照がすでに存在する場合は、既存の参照を返す必要があります。それ以外の場合は、新しい参照を返す必要があります。このようなこと:インターンをサポートするオブジェクトを作成するための良いパターン?

Foo a = new Foo(5); 
Foo b = new Foo(5); 
Foo c = new Foo(6); 
a == b 
a != c 

1)は、既存のオブジェクトのテーブルを維持するために工場の仕事である、または表は、一般的に、クラス自体の中だけの静的変数のですか?

2)既存のオブジェクトのテーブルは何ですか?インスタンスが要求されるたびに検索するオブジェクトのセットですか、またはキーがオブジェクトで値がパラメータであるマップですか?

+0

'String'のソースを見ましたか? – Paul

+0

Stringは、そのinternメソッドにネイティブコードを使用しているようです。 – Jim

+1

私は不思議です:インターナショナルをサポートするオブジェクトがなぜ必要でしょうか? –

答えて

0

既存のオブジェクトを再利用しませんnew演算子、でこれを行うことはできません。これを行うための最良の方法は工場です。 (これは、クラスの静的なnewInstanceメソッドと同じくらい簡単です)。これのための通常のデータ構造は、ある種のマップ(通常はHashMap)です。セットははるかに高価になるでしょう。オブジェクトの数に応じて、配列を使うこともできます。 (私はこれがByteのようなものかもしれません)

Stringオブジェクトは自動的にインターンされません。また、internを呼び出すと、別のStringインスタンスが返されることに注意してください。例えば、このコードは「false」を出力します:

String a = new String("hello"); 
String b = new String("hello"); 
a.intern(); 
b.intern(); 
System.out.println(a == b ? "true" : "false"); 
+0

私のFooクラスは 'static Map m'と' Foo newInstance(Integer i) 'を含み、' m.containsValue(i) 'ならばチェックしますか?私は2つの場所(オブジェクトと地図)で自分のパラメータを維持しなければならないことはちょっと奇妙に思えます。 – Jim

+1

しかし、3行目と4行目は何もしていません。それらを 'a = a 'に変更してください。intern() 'と' b = b.intern() 'を返し、" true "を返します。 – cgull

+0

@cgull 3行目は何かを行いますが、 'a'には何もしません。この例のポイント(そしておそらく私はこれを明確にしませんでした)は、設定できるインターンシップの種類にかかわらず、 'new'が常に別のオブジェクトを返すということです。 –

0

サードパーティの依存関係をGoogleグアバとそのInternersクラスを考慮追加することができます。それは2人の単純なインターナンを持っています:WeakInternerStrongInternerStrongInternerにはConcurrentMapが付いています。小さな値の閉じた値に最適です。あなたが制御することができないか、または何らかの形で収容されているものを制限することができない場合は、WeakReferenceに依存するWeakInternerを選ぶことができます。 WeakInternerのトレードオフはパフォーマンスです。

関連する問題