Java,编译后创建一个对象向量,该向量应在其数组中具有n个零

时间:2018-10-10 14:35:50

标签: java vector interface abstract extends

这有点难,但我会尽力使我的问题尽可能清楚。 因此,我正在从事一个涉及向量运算的项目。对于不同的维度,我有不同的类:Vector3D,Vector5D和VectorND。因此,我具有描述诸如Sum,Subtract等方法的接口和抽象类。对于运算结果,我创建了一个新的对象Vector,并将其放在加法/减法之后的坐标。因此,这里是部分代码示例: >

map

这里已经保护了abstart Vector resVec(); -创建新矢量的方法,该矢量的长度取决于我们使用的矢量的尺寸。 Vector3D的实现示例:

Model.new(
  name: abc.name,
  description: abc.description,
  product_ids: abc.product_ids.map(&:id) 
)

因此,在这里我创建一个长度为3的新向量,并用零填充。我需要为VectorND创建相同的向量。像这样:

interface sample
{
    Vector Sum(Vector vec);
    Vector Subtraction(Vector vec);
    int Product(Vector vec);
    boolean Compare(Vector vec);
    String ToString();
}
abstract class Vector implements sample
{       
    int[] coordinates;  
     public Vector (int[] coordinates)
     {
         this.coordinates=coordinates;
     }
    protected abstract Vector resVec();     
    public Vector Sum(Vector vec)
    {   
        Vector result = resVec();
        if (this.coordinates.length == vec.coordinates.length)
        {
            for (int i = 0; i< vec.coordinates.length; i++)
            {
                result.coordinates[i] = this.coordinates[i] + vec.coordinates[i];
            }
        }
        else 
        {
            throw new ArithmeticException("Can't sum vectors of different length");
        }
        return result;

任何想法如何传递未声明的零?也许有不同实现的任何想法?谢谢!

3 个答案:

答案 0 :(得分:1)

在resVec()方法中,您可以填充一个0s数组,然后将其传递给Vector超级构造函数。由于您的超级构造函数采用了一个整数数组,因此您可以执行以下操作:

public VectorND resVec(int n)
{
    int[] coordinates = new int[n];
    Arrays.fill(coordinates, 0);

    VectorND resVec = new VectorND(coordinates);       
    return resVec;
}

答案 1 :(得分:1)

最重要的是,您可以使用泛型,因为一旦向量类型需要float或double,就会遇到问题。

public interface Vector<T extends Number>{

    T getX();

    void setX(T x);

    // [...]

    T length();

    T lengthSquared();
    // [...]

对于您的问题,可以通过添加一个帮助变量来解决,该变量包含维数,然后将数学运算作为算法/循环处理。这样,尺寸的大小就不再重要了,并且还避免了诸如被零除的问题。

这是矩阵的一个示例..但是方法是相同的:

public final void multiply(float factor) {
    // in your case it would be getDimension() or something 
    for(int i = 0; i < getRows()*getColumns();++i){
        m[i]*=factor;
    }
}

哦,我知道这个建议对Java开发人员来说很难,但不要过度设计,否则会浪费性能。

答案 2 :(得分:0)

数组的值自动被默认。

int[] ints = new int[4];             // Filled with 0
double[] doubles = new double[5];    // Filled with 0.0
boolean[] booleans = new boolean[6]; // Filled with false
String[] strings = new String[7];    // Filled with null

我不太确定您的类,但是对于像多维矩阵这样的类,只需要一个版本即可。可以使用计算出的索引将值存储在线性数组中。

public class DoubleMatrix {
    final int[] sizes;
    final double[] values;

    public DoubleMatrix(int... sizes) {
        this.sizes = Arrays.copyOf(sizes, sizes.length); // Or sizes.clone()
        int valueCount = 1;
        for (int size : this.sizes) {
            assert size > 0 : "Every given size must be at least 1.";
            valueCount *= size;
        }
        values = new int[valueCount];
    }

    public int dimesion() {
        return sizes.length;
    }

    public double get(int... is) {
        int i = index(is);
        return values[i];
    }

    // new DoubleMatrix(2, 3, 4).set(3.14259, 0, 1, 2); // 24 values in 3D
    public void set(double x, int... is) {
        int i = index(is);
        values[i] = x;
    }

由于var-args is,设置器将值放在第一位有点不寻常。 从多个索引到索引到values数组的线性化:

    private int index(int... is) {
        assert is.length == sizes.length: "Wrong number of indices.";
        int singleI = 0;
        for (int dim = 0; dim < sizes.length) {
            if (0 > is[dim] || is[dim] >= sizes[dim]) {
                throw new IndexOutOfBoundsException();
            }
            if (dim > 0) {
                singleI *= sizes[i - 1];
            }
            singleI += is[i];
        }
    }

(我不确定索引计算是否正确。)

抛出断言,而不是抛出运行时异常(IllegalArgumentException)会更好。

当然,如果getsetprotected,则可以创建一个没有var-args的子类,并为public get(int i, int j)使用DoubleMatrix2D