I am quite new to Java, and I am constantly looking for ways to improve my code. But I don't seem to get this, if it is even possible to do.
Let's say I have this code (I edited out the irrelevant parts, so the code might seem weird):
public class NewBody {
public static int distanceScale = 5;
public int x, y;
public float xMeter = x * distanceScale;
public float yMeter = y * distanceScale;
public NewBody(int x, int y){
this.x = x;
this.y = y;
}
public void pixToMeter(){
this.xMeter = distanceScale * this.x;
}
If I don't call pixToMeter() and just try to use "instance.xMeter" directly, it just returns the vaulue 0, even though I've already set the x variable in the constructor.
So my question is: Is there a way to properly set variables without calling a method to do it? It seems highly unneccessary since I am not even passing a parameter to it.
Sorry for my poor english, I hope you understand what I am trying to say.
The initialisation of xMeter is done when x is still zero.
This is what actually happens:
public NewBody(int x, int y) {
// All fields are zeroed: 0, null, 0.0.
super(); // Object constructor, as Object is the parent class.
// Those fields that are initialized:
xMeter = this.x * distanceScale; // 0.0f * 5
yMeter = this.y * distanceScale;
// The rest of the constructor:
this.x = x;
this.y = y;
}
For a depending value:
public final void setX(int x) {
this.x = x;
xMeter = this.x * distanceScale;
}
And to apply the DRY principle (Don't Repeat Yourself): one could drop the initialisation of xMeter and call setX(x) in the constructor instead.
When called in the constructor it is important to make setX final, that is: not overridable.
The source of the problem is here:
public float xMeter = x * distanceScale;
The issue is that you're initializing this instance variable outside the constructor. As a result, since x is initialized to 0, the result of your multiplication is also 0.
If you need xMeter and yMeter initialized to a value based on x or y, simply declare them as you did the other fields:
public int xMeter;
And initialize their values in the constructor:
public newBody(int x, int y){
// initialize x and y ...
this.xMeter = x * distanceScale;
As others have mentioned, when the xMeter is initialized, the constructor is not called yet and x is still 0, so the value of xMeter is 0 as well.
To change that, you must update xMeter's value once x is initialized in the constructor, like so:
public NewBody(int x, int y){
this.x = x;
this.y = y;
// update x and y meter
xMeter = x * distanceScale;
yMeter = y * distanceScale;
}
However, you mentioned how you want xMeter to update every time x is changed as well. As it stands with your current code, that will not happen. However, a suggestion of mine would be to create a method to change the value of x (and y as well) and in those methods, also update the values of xMeter and yMeter. That way, whenever you want to change x, call the methods and it will update your other values too.
Try adding these methods and changing your constructor to this:
// called setter methods
public void setX(int x) {
this.x = x;
this.xMeter = x * distanceScale;
}
public void setY(int y) {
this.y = y;
this.yMeter = y * distanceScale;
}
// constructor
public NewBody(int x, int y){
setX(x);
setY(y);
}
Related
I'm working on a homework assignment regarding a maze of boolean values. The goal is basically to find the shortest path from start to finish if it exists. That's something I think I can handle. But!
We have been given a class called Pos that handles positions in the maze. And this is where my question comes in:
This is the class:
public class Pos implements Comparable<Pos>{
public int x, y;
Pos(int x, int y){
this.x = x;
this.y = y;
}
public int compareTo(Pos p){
return (this.x != p.x ? this.x - p.x : this.y - p.y);
}
}
The maze solver is gonna be like this:
public ArrayList<Pos> solve(Pos start, Pos finish, boolean maze[][])
Now what I was thinking about doing is getting the coordinates from start and finish and store them in variables when searching through the maze. Like startX and startY.
But here's the problem. I am wondering if this is possible without altering the Pos class? I'm not sure if I'm allowed to add getX() and getY() to the Pos class.
Any help is appreciated.
In terms of programming style, which of the following two options is better?
Option 1
public class A {
private int x, y;
public A (int z) {
this.x = z
this.y = this.x
}
}
Option 2
public class A {
private int x, y;
public A (int z) {
this.x = z
this.y = z
}
}
Both are same...
But i think if you look at code option 2 looks better because you dont even have to rad it to understand
why make things complected, if there is no benefit...
Performance wise, I don't think there is any difference. If you really must choose one, I'd go with the second one as it is easier to read and understand.
If there is an array such as:
//....
int[] anArray;
anArray = new int[3];
anArray[0] = new otherClassWConst( x, y , z);
anArray[1] = new otherClassWConst( x, y , z);
anArray[2] = new otherClassWConst( x, y , z);
//....
With the values of x and y and z all being of different value to the other x, y, and z's from the other objects in the array. (Does that make sense? Like the value of x in anArray[0] is not the same as the value found in anArray[2]). Note: there is a constructor from another class that requires those parameters, I'm not sure if thats important
How do I, in a different class, get the value of one of the parameters (for example, the value of y) in each of the array values. As in, is there a way I can get all three values of the Ys so I can add them all up together in another class?
For example
//code attaining only the y values of the array
overallValueOfY = Y + Y + Y; // or something of that nature
//life continues over here.
Please tell me if something is unclear, I tried so hard to explain. Thank you for the consideration.
OtherClassConst will need to supply a get method for it:
public class OtherClassConst {
private int x;
private int y;
private int x;
public (int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getY() {
return y;
}
/* Same concept for getX() and getZ() */
}
Then, you class can call it:
int sumY = 0;
for (OtherClassConst c : myArray) {
sumY += c.getY();
}
First off, your array won't work unless your new class extends Int, I just want to make sure you know that.
Now, all you have to do is in that new class create an int varriable
int x;
int y;
int z;
and set them equal to what is put in the constructor. Then create a new method that returns the values
public int getX(){
return this.x;
}
public int getY(){
return this.Y;
}
public int getZ(){
return this.Z;
}
You need to create POJO for your other class with x,y and z instance variables, then using setter method of y you can get the values. Iterate over them to get the sum of values.
If you other OtherClass has a getY method that returns an integer then you can use the following to sum them:
Arrays.stream(anArray).mapToInt(OtherClass::getY).sum();
It is worth getting use to using streams rather than for loops.
I have read that " a variable is shadowed if there is another variable with the same name that is closer in scope". I found this Point class with a constructor as an example:
public class Point {
public int x = 0;
public int y = 0;
public Point(int x, int y) {
x = x;
y = y;
}
}
Then I created an object of the Point class in the CreateObjectDemo class below
and printed the value of the variable x.
public class CreateObjectDemo {
public static void main(String[] args) {
Point originOne = new Point(23, 94);
System.out.println(originOne.x);
}
}
After running the compiler, it prints 0. But why doesn't it print 23? I thought that "x = x" in the constructor would be like "23 = 23". Did I misunderstand the definition of shadowing variables?
I thought that "x = x" in the constructor would be like "23 = 23".
Within the constructor, the meaning of the simple name x is always just the parameter. So the assignment x = x in the constructor takes the value of the x parameter and assigning it to the x parameter as well. The instance variable is never touched. (It's not clear what you mean by 23 = 23;, so I can't tell whether or not that's accurate.) Basically, this is a no-op and some IDEs will give you a warning about it.
To force it to copy to the instance variable, you want:
this.x = x;
(And likewise for y, of course.)
0 is the default value for int type variables, and as the warning says, you're shadowing the variables in the constructor so the object variable is never assigned to.
public Point(int x, int y) {
x = x; //assign value of local x to local x
y = y; //assign value of local y to local y
}
You need to use this keyword to refer to the object variables x and y instead of the local variables:
public Point(int x, int y) {
this.x = x; //assign value of local x to object variable x
this.y = y; //assign value of local y to object variable y
}
I have been having an issue when adding objects to an array. It seems that every single time I add a new WoodFloor object to the array, it overwrites all of the other values of the array. Here's my code:
package code;
public class Main {
private static Block[] blocks = new Block[12];
public static void main(String[] args) {
for(int i = 0; i < 12; i++) {
blocks[i] = new WoodFloor(i * 10, i * 20);
}
}
}
package code;
public class Block {
protected static int x, y;
public Block(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
package code;
public final class WoodFloor extends Block {
public WoodFloor(int x, int y) {
super(x, y);
}
}
Don't use static modifier for class fields that need to be different for each instance. The static modifier makes the field a class field, one that is effectively shared by all instances, and this is not what you want.
So change this:
protected static int x, y;
to this:
protected int x, y;
Your program produces 12 different objects, but they all reference the same pair of x and y. The problem is on this line:
protected static int x, y;
// ^^^^^^
When you make a field static, you are saying that the value of this field is going to be the same in every single object of the class. This is definitely not what you are trying to achieve here: you need each WoodFloor to have its own x and y. For that, you use instance fields (i.e. fields declared without static).
Static makes the variable available at the class lever so an instance is not needed to access it. Here effectively resets it to its original value each time rather than moving to the next array position and forgets the old array.
I'm suspecting it's the 'static' keyword for x and y.