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

Java, Creating an object vector that should have n zeros in it's array after compilation

这有点难,但我会尽量把我的问题说清楚。 所以我正在做一个处理向量操作的项目。对于不同的维度,我有不同的 classes:Vector3D、Vector5D 和 VectorND。所以我有接口和抽象 class 来描述诸如 Sum、Subtraction 等方法。对于操作结果,我创建了一个新对象 Vector,我在其中将坐标放在 sum/subtraction 等之后。所以这是代码的一部分例如:

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;

这里是有protected abstart Vector resVec(); - 创建新向量的方法,其长度取决于我们操作的向量的维度。 Vector3D 的实现示例:

class Vector3D extends Vector

{

public Vector3D(int n1,int n2,int n3) 
{
       super(new int[]{n1,n2,n3});
}

public Vector3D resVec()
{
    Vector3D resVec = new Vector3D(0,0,0);
    return resVec;
}

所以在这里我创建了一个长度为 3 的新向量并用零​​填充它。我需要为 VectorND 创建相同的向量。像这样:

    class VectorND extends Vector
{
    public VectorND(int...n) 
    {       
            super(n);
    }
    public VectorND resVec()
    {
        VectorND resVec = new VectorND();       
        return resVec;
    }

关于如何传递未声明的零数的任何想法?或者也许有任何不同实施的想法?谢谢!

在 resVec() 方法中,您可以填充一个 0 数组,然后将其传递给 Vector 超级构造函数。因为你的超级构造函数接受一个整数数组,你可以这样做:

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

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

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

public interface Vector<T extends Number>{

    T getX();

    void setX(T x);

    // [...]

    T length();

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

对于你的问题,可以通过添加一个包含维度数量的辅助变量来解决,而不是将数学运算作为算法/循环来处理。这样维度的数量就不再重要了,你也可以避免被零除之类的问题。

这是一个矩阵的例子..但是aproche是一样的:

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 开发人员来说很难,但不要过度设计它,否则你会浪费性能。

数组的值自动默认。

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

我不完全确定你的 classes,但是对于 multi-dimensional matrix-like class 只需要 one 版本。这些值可以使用计算出的索引存储在线性化数组中。

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

setter 由于 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,你可以制作一个 child class 而没有 var-args,并有一个 public get(int i, int j) 对于 DoubleMatrix2D.