[英]Java Generic Primitive type n-d array
我必须将原始的2d数组传递给过滤例程。无论数组的类型如何,过滤算法(中值过滤器)都是相同的。有没有办法以通用方式传递任何类型的数组,或者我应该重载具有不同数组类型的相同功能。在第二种情况下,必须针对不同数据类型重复相同的代码。
int[][] medianfilter(int[][] arr){ ... }
float[][] medianfilter(float[][] arr){ ... }
有没有办法使上面的代码成为通用代码,而不是在每个重载函数中重复使用medianfilter的代码?
以通用方式传递它并将其保持为原始数组的唯一方法是作为Object
。 就个人而言,我只是重载它,并将其视为使用原语的成本。
为了避免算法中的代码重复(如果它是很多代码),你可以使用抽象方法(如double getElement(int i, int j)
和handleResult(double result)
生成一个名为DoubleAlgorithm
的抽象类,然后写入这个的小子类,每个基本类型一个。
让我用一个例子来解释(假设算法正在添加数字)。
public int filter(int [][] values) {
IntAlgorithm algo = new IntAlgorithm(values);
algo.run();
return algo.getResult();
}
public double filter(double [][] values) {
DoubleAlgorithm algo = new DoubleAlgorithm(values);
algo.run();
return algo.getResult();
}
public class AbstractAlgorithm {
public run() {
double sum = 0.0;
for(int i=0; i<rows(); i++) {
for(int j=0; j<columns(i); j++) {
sum+=getElement(i, j);
}
}
handleResult(sum);
}
protected abstract int rows();
protected abstract int columns(int row);
protected abstract double getElement(int i, int j);
protected abstract void handleResult();
}
public class IntAlgorithm extends AbstractAlgorithm {
int [][] values;
int result;
IntAlgorithm(int [][] values) {
this.values= values;
}
public int rows() {
return values.length;
}
public int columns(int row) {
return values[row].length;
}
public double getElement(int i, int j) {
return values[i][j];
}
public void handleResult(double result) {
this.result = (int)result;
}
public int getResult() {
return result;
}
}
正如您所看到的,它非常冗长,但如果您的算法很大,那么它可能是值得的。 希望很明显如何扩展到您的算法。
正如Thilo指出的那样,将所有算法仅仅作为双精度来处理所有算法是不安全的,但是对于一个数字来说它就足够了。 如果它不适合你,那么你需要更加详细,找出你需要的数字属性(例如添加)并将它们提取到一个单独的界面。 对于中值滤波器,我希望只使用双精度工作正常,但我会测试边缘情况。
对于原始数组没有好的方法,这就是为什么所有库函数(例如java.util.Arrays)也都有这些重复的方法。
您可以定义一个方法
Object[] medianfilter(Object[] arr); // note the missing dimension
并使用反射来找出运行时类型。 这就是System.arraycopy正在做的事情。 但是你需要进行类型转换。 丑陋。
int[][] result = (int[][]) medianFilter( input );
使用重复的方法。
有一种方法可以通用方式传递数组的类型:
public T test(T[][] arg)
{
T[][] q = arg;
T[] r = q[0];
T s = r[0];
return s;
}
...不幸的是,它不适用于原始类型。 您需要使用Integer和Float作为参数化类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.