这有点难,但我会尽力使我的问题尽可能清楚。 因此,我正在从事一个涉及向量运算的项目。对于不同的维度,我有不同的类: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;
任何想法如何传递未声明的零?也许有不同实现的任何想法?谢谢!
答案 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)会更好。
当然,如果get
和set
是protected
,则可以创建一个没有var-args的子类,并为public get(int i, int j)
使用DoubleMatrix2D
。