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; } 
2
  • 1
    Why not do it in two calls? myVector.multiply(-1D)) then doSomething(myVector); . Commented Oct 30, 2017 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. Commented Oct 30, 2017 at 18:31

3 Answers 3

8

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

public Vector multiply(double factor) { return new Vector(X * factor, Y * factor); } 
Sign up to request clarification or add additional context in comments.

4 Comments

Yeah and also add another multiply function void modifing the self object ?
I agree with the approach, please elaborate on what it means to make the class immutable.
@BernieNoël No, immutable means the object is unchanging. Any modification produces a new copy. This makes your code safer and easier to reason about, especially in multithreaded environments.
and change the method name to scale.
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.

2 Comments

How is this different from shmosel's answer?
It is not different but I guess we published almost simulatenously
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;.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.