I have been attempting to make a linear algebra library in Java. I had a Vector class and Complex Number class already created, where the Vector class already had methods and operations which worked with real numbers (typical doubles and ints). The Vector class previously had an attribute data[] which contained the values for the numbers in the vector. However I now added other attributes cData[] and isComplex - which if the Vector is initialized with a different constructor, isComplex is set to true and cData contains the Complex values for the Vector. My goal is to make the class as seamless to the user as possible so that they can create a Vector with either real or complex values with the same class.
However, I was running into some errors due to the nature of Java. Specifically my .get() method would have to have two different return types depending on whether isComplex is true or not which is not possible. This is because I was intending to return a real value (double) if the Vector was Real and a complex value (Complex) if the Vector was initialized as complex. Does anyone have any ideas on what I could try or what routes I could take to better structure this class? (attributes/methods/etc)
So far my ideas have been
Here is my current approach and a couple of methods:
public class Vector {
private double[] data;
private Complex[] cData;
private boolean isComplex = false;
public final int length;
public Vector(double[] vector) {
this.data = vector;
this.length = vector.length;
}
public Vector(String[] vector) throws ConstructFormatException {
Complex[] array = new Complex[vector.length];
for(int i = 0; i < vector.length; i++){
array[i] = new Complex(vector[i]);
}
this.cData = array;
this.isComplex = true;
this.length = vector.length;
}
public void add(Vector vector) throws OperationUndefinedException{
if(this.isComplex){
//
} else {
MatrixOperation function = (d1, d2) -> {return d1 + d2;};
applyOperation(vector, function);
}
}
public double get(int index) throws OperationUndefinedException{
if(index >= data.length){
throw new OperationUndefinedException(INDEX_OUT_RANGE);
}
return data[index];
}
}
By the code snippet you have provided I guess you want to have the ability to mix real value vectors and complex value vectors on the go. Achieving this with a single class may be a bit problematic, so the solution I would propose is next. Create one generic interface Vector<T>
, create functions for both, Vector<Double>
and Vector<Complex>
. After that create two classes which implement their respective functions. for example: class ComplexVector implements Vector<Complex>
and class RealVector implements Vector<Double>
.
Throw unsupported operation wherever applicable (like some java.util.List
implementers do).
This approach will give u flexibility to define functions in vector interface either using Generic 'T' or using specific double
/Complex
types wherever you find fit
Edit: you can have a bool isComplex()
function in the interface and both children will implement accordingly, which will give you freedom in your implementations. However you should make sure users won't try to have their own implementations of your Vector
interface, or your structure may loose its "seamlessness". Other than that, users will be able to interact with your two child classes directly and interchange between them without problem