2

Stackoverflowers さん、こんにちは。

次の問題があります。

入力としてプリミティブ数の配列を取得する状況があります。たとえば、int[] または short[] または byte[] などです。ここで、コードを反復処理して特定の処理を行う必要があります。たとえば、数値をリストに書き込むなどです。ただし、問題は、すべてのタイプの数値に特定のリストが必要なことです。問題ありません、と私は思い、ジェネリックを使用しようとしました:

Object dataSet = provider.getDataArray();
Number[] copy = new Number[Array.getLength(dataSet)];
for(int i= 0; i < Array.getLength(dataSet); i++) {
    copy[i] = (T) Array.get(dataSet, i);
}

これは美しく機能します。ただし、問題はパフォーマンスにあります。リフレクションと発生するプリミティブのボクシングはコストがかかるため、回避できないことはわかっています。私は今、コードの量を減らすためのパターンを探しています。

Object dataSet = provider.getDataArray();
Class<? extends Number> dataType = provider.getDataType();

Number[] copy = new Number[dataSet.length];
if(dataType == Float.class) 
    float[] dataSetAsFloat = (float[]) dataSet;
    for(int i= 0; i < dataSet.length; i++) 
        copySet[i] = dataSetAsFloat[i];
else if (dataType == Double.class)
    double[] dataSetAsDouble = (double[]) dataSet;
    for(int i= 0; i < dataSet.length; i++) 
        copySet[i] = dataSetAsFloat[i];    
....

私が書いているプログラムのアプリケーションはここに示されているほど単純ではないため、非常に肥大化したソリューションです。基本的に、このパフォーマンスの問題のために、数百行の余分なコードを作成します。これに対する解決策はありますか?おそらく、私が認識していないパターン、または私が見ていない本当に単純なトリックでしょうか?

私は応答に非常に感謝しています。

ありがとう。

4

2 に答える 2

1

データ型に基づいて変換戦略を選択する戦略パターンを検討しましたか?全体的なコード全体の多くを減らすことはありませんが、モジュール化するのに役立ちます。

public interface ArrayConversionStrategy<T extends Number> {
    T[] convertArray
}

public class FloatConversionStrategy implements ArrayConversionStrategy<Float>
   float[] convertArray(Object[] dataset) {
     float[] dataSetAsFloat = new float[dataset.length];
      for(int i= 0; i < dataSet.length; i++) 
        dataSetAsFloat [i] = dataset[i];
  }
}

public class DoubleConversionStrategy { ... }
public class LongConversionStrategy { ... }

次に、呼び出し元のクラスに、データ型から戦略へのマップがあります

Map<Class<? extends Number>, ArrayConversionStrategy> map;

Object[] dataSet =    provider.getDataArray();
Class<? extends Number> dataType = provider.getDataType();
ArrayConversionStrategy strategy = map.get(dataType)
return strategy.convertArray(dataSet);

私の一般的な構文のいくつかはここから外れていて、実行する必要があるかもしれないいくつかのボクシング/自動アンボックスを持っているかもしれませんが、一般的な戦略としてこれは役に立つかもしれません。

于 2012-07-04T18:31:34.847 に答える
0

ラッパーをアンパックする代わりに、整数には getLong(int)/putLong を、浮動小数点には getDouble(int)/putDouble を使用できます。これにより、すべてのプリミティブ タイプをサポートする 2 つのメソッドが得られます。

interface Array {
    public long getLong(int idx);
    public double getDouble(int idx);
    public void setLong(int idx, long l);
    public void setDouble(int idx, double d);
}

class ByteProvider implements Array {

}

class IntProvider implement Array {

于 2012-07-04T18:20:53.110 に答える