简体   繁体   English

Java Generic Primitive类型nd数组

[英]Java Generic Primitive type n-d array

I have to pass a primitive 2d array to a filtering routine.The algorithm for filtering(median filter) is same irrespective of the type of the array.Is there a way to pass any type of array in a generic manner or should I overload the same same function with different array types.In the second case the same code will have to be repeated for different data types. 我必须将原始的2d数组传递给过滤例程。无论数组的类型如何,过滤算法(中值过滤器)都是相同的。有没有办法以通用方式传递任何类型的数组,或者我应该重载具有不同数组类型的相同功能。在第二种情况下,必须针对不同数据类型重复相同的代码。

int[][] medianfilter(int[][] arr){ ... }
float[][] medianfilter(float[][] arr){ ... }

Is there a way to make the above code a generic one,instead of repeating the code for medianfilter in each an every overloaded function ? 有没有办法使上面的代码成为通用代码,而不是在每个重载函数中重复使用medianfilter的代码?

The only way to pass it in a generic manner and keep it as a primitive array is as an Object . 以通用方式传递它并将其保持为原始数组的唯一方法是作为Object Personally, I'd just overload it, and see it as a cost of using primitives. 就个人而言,我只是重载它,并将其视为使用原语的成本。

To avoid duplication of code in the algorithm (if it is a lot of code) you could produce an abstract class called something like DoubleAlgorithm with abstract methods like double getElement(int i, int j) and handleResult(double result) and then write very small subclasses of this, one for each primitive type. 为了避免算法中的代码重复(如果它是很多代码),你可以使用抽象方法(如double getElement(int i, int j)handleResult(double result)生成一个名为DoubleAlgorithm的抽象类,然后写入这个的小子类,每个基本类型一个。

Let me explain with an example (suppose the algorithm was adding the numbers). 让我用一个例子来解释(假设算法正在添加数字)。

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;
    }
}

As you can see, it is quite verbose, but if your algorithm was big it might be worth it. 正如您所看到的,它非常冗长,但如果您的算法很大,那么它可能是值得的。 Hopefully it is obvious how to extend to your algorithm. 希望很明显如何扩展到您的算法。

As Thilo has pointed out, it isn't safe to do all algorithms with just treating ints/longs as doubles, but for a number it will be good enough. 正如Thilo指出的那样,将所有算法仅仅作为双精度来处理所有算法是不安全的,但是对于一个数字来说它就足够了。 If it isn't for you, then you need to go even more verbose, work out which properties of numbers you need (eg add) and extract those to a separate interface. 如果它不适合你,那么你需要更加详细,找出你需要的数字属性(例如添加)并将它们提取到一个单独的界面。 For a median filter, I would expect just using doubles will work fine, but I'd test the edge cases. 对于中值滤波器,我希望只使用双精度工作正常,但我会测试边缘情况。

There is no good way to do this for primitive arrays, which is why all the library functions (such as java.util.Arrays) also have these duplicated methods. 对于原始数组没有好的方法,这就是为什么所有库函数(例如java.util.Arrays)也都有这些重复的方法。

You could define a method 您可以定义一个方法

Object[] medianfilter(Object[] arr); // note the missing dimension

and use reflection to find out the runtime type. 并使用反射来找出运行时类型。 This is what System.arraycopy is doing. 这就是System.arraycopy正在做的事情。 But you then need to type-cast. 但是你需要进行类型转换。 Ugly. 丑陋。

int[][]  result = (int[][]) medianFilter( input );

Go with the duplicated methods. 使用重复的方法。

There is a way to pass the type of an array in a generic manner: 有一种方法可以通用方式传递数组的类型:

public T test(T[][] arg)
{
    T[][] q = arg;
    T[]   r = q[0];
    T     s = r[0];

    return s;
}

... unfortunately it won't work for primitive types. ...不幸的是,它不适用于原始类型。 You'll need to use Integer and Float as your parameterized types. 您需要使用Integer和Float作为参数化类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM