2014-12-31 9 views
6

List<T>に、メソッドに宣言しなかった一連の許可された型を渡すにはどうすればよいですか。リストで使用するJavaの型を制限する

など。私はリストを使用している場合、私はParentのすべてのインスタンスを置くことができます

public void method(List<Object> myList); 

と:私はList<Object>を使用している場合、私はそのリストにすべてを置くことができ

// Pseudo code 
public void method(List<Integer OR Boolean OR String> myList); 

:整数、ブールとStringに種類を制限そのサブクラスをそのリストに追加します。

public void method(List<Parent> myList); 

これで十分です私はそれらのサブクラス(AllowedTypeA extends Parent)を宣言する人です。しかし、私が使用したいクラスのオーナーでないときはどうすればいいですか(IntegerParentを延長することはできません)?

+0

あなたは表現する "または" Javaで制約を入力することはできません。そのような制約が必要な実装しようとしている方法を説明できますか? –

+1

ジェネリックはおそらく間違った解決策です。彼らは "ジェネリック"なので、その名前です。特定の型のみをサポートできる場合(またはその型に固有のロジックを持つ場合)、特定の型ごとにメソッドがオーバーロードされている可能性があります。 – mellamokb

+3

@mellamokbこの場合、オーバーロードがうまくいかないかもしれませんが、 'List <...>'引数のすべてが 'List'に消去されるので、他のパラメータ(または名前が異なっていて、それがオーバーロードしていない場合) )。 –

答えて

2

概念的には、私は@ launeの解決策をもっと好むでしょう。私は型の安全性を望んでいて、リストにたくさんのものを投げ込み、許容された型を追加するのを忘れることなく、エラーをコンパイルします。

これは言いますが、これを実行するために余分な作業をする必要がありますが、オブジェクトタイプを削除すると、関連するすべてのオブジェクトも削除する必要があります適切な機能を確保するためには、addAllのように他のメソッドをオーバーライドする必要があります。

この方法では、いつでもallowedTypesを追加できるので、launeに比べて柔軟性があります。あなたの状況のた​​めに、おそらく最高ではないが、一般的な質問はまだ私がショットを取ったほど興味深いです。たぶん、リストの中には整数を格納したいが、他のものは格納しないでください。 addPermittedObjectメソッドを使用するとそうすることができます。

public class SelectiveList extends ArrayList<Object> { 
    //the (types of) objects that we can store 
    private ArrayList<Object> permittedObjects = new ArrayList<Object>(); 

    // put an Object type into the list 
    public boolean addPermittedObject(Object o) { 
     for (Object type : permittedObjects) { 
      if (type.getClass() == o.getClass()) { 
       return false; // if we already have it, do not add it again 
      } 
     } 
     return permittedObjects.add(o); // else let's add it 
    } 

    // remove the Object type 
    public boolean removePermittedObject(Object o) { 
     for (Object type : permittedObjects) { 
      if (type.getClass() == o.getClass()) { 
       return permittedObjects.remove(type); 
      } 
     } 
     return false; 
    } 

    @Override 
    public boolean add(Object o) { 
     for (Object type : permittedObjects) { 
      if (type.getClass() == o.getClass()) { 
       return super.add(o); // go ahead and add the item since it 
             // matches our list 
      } 
     } 
     return false; 
    } 
} 

そして、それをテストするために:

public static void main(String[] args) { 
    SelectiveList selectiveList = new SelectiveList(); 
    selectiveList.add("Potato"); 
    selectiveList.add(1); 
    selectiveList.add(true); 
    System.out.println(selectiveList.size()); // prints 0 
    // these objects need to be initialized, but their contents do not 
    // matter 
    selectiveList.addPermittedObject(new String()); 
    selectiveList.addPermittedObject(new Boolean(false)); 
    selectiveList.addPermittedObject(new Integer(1)); 
    selectiveList.add("Potato"); 
    selectiveList.add(1); 
    selectiveList.add(true); 
    System.out.println(selectiveList.size()); // prints 3 
} 
+0

型の安全なアプローチか、非常に柔軟な(実行時に構成可能な)アプローチが望ましいかどうかは、しばしば決定されます。 – laune

+0

いくつかのオブジェクトを不必要に置いておくオブジェクトの代わりに 'List > permittedTypes'にクラスを保持し、型を設定するだけで代理人を作成することが望ましいでしょう。 – laune

7

行うための最善のことは、クラスの中に、この混合リストをラップし、あなたが許可したいだけで何追加するための方法を提供することである。

class WrappedMix { 
    private List<Object> oddsAndEnds = ... 

    public void add(Integer el){ oddsAndEnds.add(el); } 
    public void add(Boolean el){ oddsAndEnds.add(el); } 
    public void add(String el){ oddsAndEnds.add(el); } 
} 

または適切なオーバーライド(およびオーバーロード)でのArrayListを拡張し、

なぜこのようなリストが必要なのか不思議ですが、処理が便利ではありません。

+0

ほぼ完璧な、thx!しかし、これは 'List'ではない。指定したオブジェクトが 'add()'メソッドの内部で 'instanceOf'' Integer'、' Boolean'、 'String'でない場合、' List 'を実装し、' IllegalArgumentException'を投げます。 –

+0

あなたが望むならば、 'List'を拡張するカスタムクラスを作ると、' CustomList 'を持ち、より簡単に' instanceOf'を扱うことができます。 – mbomb007

関連する問題