2

目的: 必要なのは、さまざまなタイプのパラメーターを処理する関数を作成することListです。関数内のリストを反復処理します。

試み:

1- 異なるタイプのリストを持つ複数の関数

public static int update(List<MyClass> myClasses){};
public static int update(List<Project> rojects){};
public static int update(List<Time> times){};

しかし、同じパラメータタイプを持つ複数の関数が原因で、コンパイルできないと見なされますList

2- 一般的なタイプのリスト、および ( instanceof) の使用 しかし、方法がわからないため、これを完全に行うことはできませんでした。

私の質問: そのような要件を実装する Java の方法は何ですか? きれいなコードが必要です。複雑であっても気にしません。主に正確さと適切なコーディングに関心があります。

PS:instanceof正しい方法であれば、リストをさまざまなタイプで反復処理する方法の小さな例を教えてください。

前もって感謝します :)

EDIT : 異なるオブジェクトは相互に関係がありません。相互に拡張したり、スーパークラスを拡張したりしません。各関数のブロックは、タイプごとに異なる SQLite ステートメントを生成しています。


'厳しい答え:

したがって、私はあなたの提案の組み合わせを使用することになりました。つまりgetClassType()、クラス名の文字列を返す関数を使用して基本クラスを実装し、関数で返された値を確認しupdate(List<T> list)ます。

public static <T extends Item> int update(List<T> list){
    ...
    // Loop through the list and call the update function
    for (T item: list){
        if (item.getClassType() == MyClass.CLASS_TYPE)
            update((MyClass) item);

    }
    ...
}

public interface Item {
    /**
     * @return Return the class type, which is the name of the class
     */
    public String getClassType();
}

public class ClassProject implements Item{
    public static final String CLASS_TYPE = "ClassProject";
    @Override
    public String getClassType() {
        return CLASS_TYPE;
    }
    ...
}

public class ClassTime implements Item{
    public static final String CLASS_TYPE = "ClassTime";
    @Override
    public String getClassType() {
        return CLASS_TYPE;
    }
    ...
}

public class MyClass implements Item{
    public static final String CLASS_TYPE = "MyClass";
    @Override
    public String getClassType() {
        return CLASS_TYPE;
    }
    ...
}

これを全部作る理由interfaceは、私はそれが好きistanceofではなく、パフォーマンスとコストについてもわからないため、自分で作成しようとしました。今、これはこれを行うひどい方法ですか?

4

3 に答える 3

4

次のようなことができますか:

public class Update<T>
{

public static int update(List<T> objects){};

}

また

public static <T> int update(List<T> objects){};

あなたのケースでより適切なものはどれでも。

したがって、2 番目のアプローチを使用した場合、実行時の型消去のために、instanceof チェックが残ります。

public static <T> int update(List<T> objects){
        for(T object : objects)
        {
            if(object.getClass().isInstance(Pair.class))
            {
                //do something
            }else if(object.getClass().isInstance(Time.class))
            {

            }
        }
        return 0;
    }

しかし、それは良いデザインに見えません。ファクトリ メソッドを使用して上記を改善できます。

    static Handler getHandler(Class<?> handlerClass)
        {
            if(handlerClass.isInstance(Project.class))
            {
                //return ProjectHandler
            }else if(handlerClass.isInstance(Time.class))
            {
                //return TimeHandler
            }
            //return errorHandler
        }
        interface Handler {
            int handle();
        }
       public static <T> int update(List<T> objects){
            for(T object : objects)
            {
                getHandler(object.getClass()).handle();
            }
            return 0;
        }

IMO のより良いアプローチは、マーカー インターフェイスを介して更新対象のクラスを指定し、各クラスで更新をきれいに処理することです。

    interface Updateable {
        int update();
    }

    public static <T extends Updateable> int update2(List<T> objects){
        for(T object : objects)
        {
            object.update();
        }
        return 0;
    }
于 2013-05-20T11:17:20.757 に答える
1

私のコメントに対するあなたの答えに基づいて、2つのアプローチが残されています。1 つ目は、このメソッドに渡される可能性のあるすべての型が実装するインターフェイスを考え出すことです。インターフェイスが Foo と呼ばれる場合、メソッドを次のように定義できます。

public int update(List<Foo> list)

次に、内部のコードは、Foo で使用可能なメソッドに基づいています。

これができない場合は、可能なタイプごとに個別のメソッドが必要になります。Type Erasure のため、実行時に instanceof を実行することはできません。コンパイルされたコードでリストが消去され、そのため instanceof ロジックで使用できない場合の基になる型。

編集:上記の回答で少し混乱を解消するために。instanceof次のように、リストを反復するときに要素ごとに実行できます。

for(Object item:list){
  if (item instanceof A){
    //do A based logic
  }
  else if (item instanceof B){
    //do B based logic
  }
}

ただし、次のように実行時にリストの種類を確認することはできません。

if (list instanceof List<A>)

あなたの最善の策は、私の最初の解決策で提案されているように、インターフェイスを介してサポートされている型を一般化することです。instanceof アプローチを実行すると、サポートされる型を追加するたびにコードを常に変更する必要があります。

于 2013-05-20T11:36:48.373 に答える
0

過酷な答えを広げて、できませんか:

public class Update
{

public static <T> int update(List<T> objects, Class<T> clazz){};

}

そして、あなたの実装では、渡された Class インスタンスに応じて動作を変えますか?

于 2013-05-20T11:55:14.180 に答える