用Java中的原语规避代码膨胀的模式

时间:2012-07-04 18:13:06

标签: java performance design-patterns primitive boxing

你好伙伴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];    
....

是一个非常臃肿的解决方案,因为我写的程序中的应用程序并不像这里所示那么简单。基本上,由于这个性能问题,我创建了几百行额外的代码。这个问题有方法解决吗?也许是我不知道的模式,或者我看不到的一些非常简单的技巧?

我非常感谢你的回应。

感谢。

2 个答案:

答案 0 :(得分: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);

我的一些通用语法可能在这里可能有一些可能需要完成的装箱/自动装箱,但作为一般策略,这可能是有用的。

答案 1 :(得分:0)

您可以使用getLong(int)/ putLong作为整数,使用getDouble(int)/ putDouble作为浮点数,而不是解压缩包装器。这将为您提供两种支持所有基元类型的方法。

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 {