A lot of this depends on where the data is coming from and what you need to do with it. For example, if all you were doing is reading it in from a file and passing it to a calculation, you might not need an object.
The problem with the first option is that it can be very difficult to keep track of which index refers to what. There's a lot of cognitive overhead of understanding such code especially when there are a lot of properties. E.g., What was index 7, again? Was it width or depth?
The problem with the second option is that if you need to represent the data as a vector, you take on the overhead of creating these objects and copying the data to and from the arrays. If you have a large dataset, this could be problematic. If you are working with a limited number of arrays, it probably won't matter.
There's a third option that you don't mention. Instead of a class definition with dedicated fields for each element in a given vector, you can create a class which accepts (a reference to) an array of doubles and 'understands' the context and meaning of each index in the array. A simplified example follows:
class PointVector {
private final double[] data;
/* A: to create a new vector with all elements initialized to 0 */
PointVector() {
this.data = new double[3];
}
/* B: To construct a new vector from parameters */
PointVector(dobule x, double y, double z) {
this.data = new double[]{x, y, z};
}
/* To create an object wrapping an existing vector */
PointVector(double[] data) {
if (data.length < 3) throw new AnExceptionOfSomeType("bad input");
this.data = data;
}
public double getX() {
return data[0];
}
public double getY() {
return data[1];
}
public double getZ() {
return data[2];
}
/* if you want/need to modify data ... */
public double setX(double value) {
data[0] = value;
}
public double setY(double value) {
data[1] = value;
}
public double setZ(double value) {
data[2] = value;
}
/*
* if you uses constructors like A and B,
* you'll probably need a way pass the array out.
*/
public double[] asArray() {
return data;
}
}
Again, this is a simplified example and you would adapt it to your needs. For example, you might want to create brand new vectors from this class instead of simply accepting them.
The idea here is that you can avoid the overhead of converting to and from the vector representation while being able to work with the data in an a more self-documenting and understandable way.
This should be common knowledge to any Java developer but it's key to understand that, in Java, and other similar languages, the elements of arrays are always mutable. If your requirement is that you must work with raw arrays at some level and you want to use this approach, you should avoid manipulating the data outside of these objects if possible. Doing so will make the program much more difficult to reason about.
One thing that may or may not be obvious here is that, instead of an immutable reference to the data array, you could make it possible to use the same instance and repoint it on different arrays. This would mean you don't need to create an object for every array you need to work with. This might make sense for your purposes, but I would caution that this kind of thing can have some unintuitive impacts on performance. In order for that to be effective, you would need to keep one or more instances of this object around for a while and objects that live for long time before they are eligible for GC can be more expensive to manage that objects that have very short lifespans. So, if you were to use one or more 'sliding window' objects, I would make them permanent for the life of the application. Java tends to work best with fruit flies and highlanders. Try to avoid objects that live for many GC cycles and then go away.
x, y, z
fields will be much easier to use since they provide clear meaning. And if you're already defining a class, you can add helpful methods likenorm()
ordot()
to it. But this isn't really OOP, and probably shouldn't be. Sometimes, classes are just a helpful way to structure your data, no fancy principles involved.Array of Structs
vsStruct of Arrays
could be relevant here. See for example: stackoverflow.com/q/40163722/1051292