3

Hey I'm actually working with a custom Vector class on Java,

public class Vector {

    private double X;
    private double Y;

    public Vector(double x, double y) {
        this.X = x;
        this.Y = y;
    }

    public void setX(double x) {
        this.X = x;
    }
    public double getX(double x) {
        return this.X;
    }

    public void setY(double y) {
        this.Y = y;
    }
    public double getY(double y) {
        return this.Y;
    }

}

I wanted to add the multiply() method that would return this vector * by the specified factor like that,

public void multiply(double factor) {
    this.X *= factor;
    this.Y *= factor;
}

The thing is, when I use a function requiring a vector, I'd like to use it like

doSomething(ancientVector.multiply(-1D));

but the jvm isn't satisfied because the arg I send to the function is a void...

How could I also do to make it clean, should I implement Cloneable or create another constructor working the way multiply does?

doSomething(ancientVector.multiply(-1D));

OR add

public Vector(Vector previous, double mFactor) {
    this.X *= previous.getX() * mFactor;
    this.Y *= previous.getY() * mFactor;
}
  • 1
    Why not do it in two calls? ```myVector.multiply(-1D))``` then ```doSomething(myVector);``` . – Freiheit Oct 30 '17 at 18:25
  • My question would by why `Vector` is mutable at all. Why have a `setX` and `setY` method at all. Seems like if something like that is changing then you're effectively creating a new Vector. – StriplingWarrior Oct 30 '17 at 18:31

3 Answers3

8

I would keep the class immutable and return a new Vector:

public Vector multiply(double factor) {
    return new Vector(X * factor, Y * factor);
}
shmosel
  • 49,289
  • 6
  • 73
  • 138
1

You could do as @Basti said or you could also return a new instance of your Vector:

public Vector multiply(double factor) {
    return new Vector (this.X * factor, this.Y * factor);
}

This way when any change is made to the result of your multiply function it does not affect the initial vector object.

alainlompo
  • 4,414
  • 4
  • 32
  • 41
1

Your Vector will have various operations (you've started with multiply) and its usage looks similar to Java API classes such as BigDecimal. I would therefore recommend following its lead, and make the class immutable. That means all its fields should be final:

public class Vector {
    private final double x, y;              // Note: final. And use lowercase.

    public Vector(double x, double y) {
        this.x = x;
        this.y = y;
    }

    // Note: no setters!

    public double getX() {                  // Note: no argument.
        return x;
    }

    public double getY() {
        return y;
    }

    public Vector multiply(double factor) {
        return new Vector(x*factor, y*factor);
    }

}

One of the advantages of immutable classes is that they are purely value-based so you don't have to worry about copy constuctors or cloning. (By the way, Cloneable is hardly ever used nowadays – copy constructors are preferred – except perhaps for arrays.) Instead of copying, just use assignment: Vector secondVector = firstVector;.

DodgyCodeException
  • 5,963
  • 3
  • 21
  • 42