1

以下の擬似コードのように、1つのメソッドから2つの異なるタイプのクラス(List<double[]>または)を返したいと思います。List<Double[]これを達成する方法は?

編集されたコードとコメント:これは戻り値またはデータ型を変更するために要求されるため、Eclipseはコンパイルさえ許可しません。YserieScaledCastedは手動でキャストする必要があることを理解しています。

protected List<E[]> getYserieRescaledList(Class<E> c) {

    if (Double[].class == c)
        return this.YserieScaled;
    else if (double[].class == c)
        return this.YserieScaledCasted;

}

EDIT2:私の問題の正解は、ここで説明されているようにメソッドをオーバーロードすることです。

4

3 に答える 3

2

配列のリストを返していることに気づきましたよね?:-)

短い答え:

  • を渡してもClass<E>、ジェネリック型でinstanceof演算子を使用できないため、上記のifステートメントを実行できません。

  • 以下は違法であり、2つのinstanceof演算子のそれぞれでコンパイルされません。

class trash {
    protected <T> List<T[]> getYserieRescaledList(Class<T> cl) {
       List<T[]> result = null;
       if (cl instanceof Class<Double>) {
               result = ...;
       } else if (cl instanceof Class<double>) {
               result = ...;
       }
       return result;
    }
}
  • この理由は、ジェネリックはコンパイル時のみの構成であるためです。インスタンス化されたすべてのジェネリッククラスは、型が挿入され、型キャストが実行されるなど、非ジェネリッククラスに変換されます。ジェネリッククラスが実行時に特定の型でインスタンス化されるかどうかを尋ねるのは意味がありません。ジェネリッククラスは非ジェネリッククラスに交換されています。ジェネリッククラス

  • 代わりに、ifステートメントを切り取り、インスタンス化された型を使用して変数と配列を宣言し、アルゴリズムを使用してそれらにデータを入力し、結果を返します。

class treasure {
    protected <T> List<T[]> getYserieRescaledList(Class<T> cl) {
       List<T[]> result = null;
       // apply general algorithm here to populate the array
       // will work identically whether instantiated with Double or double
       return result;
    }
}

長い答え:

ジェネリッククラスは、さまざまな特定のインスタンス化されたタイプに適用できる一般化された処理の「テンプレートロジック」を表す必要があります。

良い例は、Javaコレクション、永続性クエリフレームワーク(JPA Criteria APIなど)、さまざまな種類の投資のための金融電卓、または標準サービスの「コンテナ」インフラストラクチャロジックを備えたSOAサービステンプレートです。

あなたの場合、疑似メソッドのオーバーロード(つまり、名前がわずかに異なる2つのメソッド)を使用する方が簡単な場合があります。

protected List<Double[]> getYserieRescaledList() {
    return this.Y;
}

protected List<double[]> getYserieRescaledList2() {
    return this.YCasted;
}

またはさらに良いことに、唯一のケースとしてdouble[]に固執するだけです。コンパイラは、値を他の変数/メソッドパラメータに抽出するときに、必要に応じてdoubleからDoubleへのオートボックス変換を透過的に実行します。

于 2012-11-02T02:43:18.010 に答える
1

Double[].classとを使用するだけdouble[].classです。Double[]をにキャストすることはできず、double[]その逆もできないことに注意してください。手動でコピーする必要があります。List<Double[]>したがって、拡張すると、どちらにもキャストできませんList<double[]>編集:一見すると、これはあなたが修正しようとしている制限である可能性があります。

于 2012-11-02T00:13:32.797 に答える
1

ここで起こっているいくつかの興味深いことがあります。つまり、あなたList<double[]>はプリミティブを含むList<Array>オブジェクトです。Arraydouble

ここでは、ジェネリックは適切な解決策ではないと思い切って言います。

あなたの最善の策は、Googleリストライブラリを使用することだと思います。

このようなもの:

protected List<Double[]> getYserieRescaledList() {
   return this.YseriesScaled;
}

次に、あなたgetYseriesRescaledList()を呼び出すものは何でも、このようなことをして:を取得することができますList<double[]>

Lists.transform(getYseriesRescaledList()、toPrimitiveDouble());

これにより、以下の関数(Google Guavaから)を使用して、1行のコードでListオブジェクトが作成されます。

private Function<Double[], double[]> toPrimitiveDouble(){
    return new Function<Double[], double[]>() {
        @Override
        public double[] apply( Double[] doubles) {
            double[] doubleArray = new double[doubles.length];

            int i = 0;
            for (Double doubleObject : doubles){
                doubleArray[i] = doubleObject.doubleValue();
                ++i;
            }

            return doubleArray;
        }
    };
}
于 2012-11-02T00:55:35.957 に答える