I'm creating a Vector2 class in Java, and have an issue:
public class Vector2 {
public static final Vector2 ZERO = new Vector2(0,0);
...
}
in another class, I'd like to call ZERO like this:
Vector2 myVector = Vector2.ZERO; //initialize to zero
myVector.add(myOtherVector); //myVector is now the sum of Vector2.ZERO and myOtherVector
However, this behaves undesirably: myVector just becomes Vector2.ZERO--and thus unchangeable--rather than being initialized to the zero value and then being free to work with as I wish. To get the behavior I want, I need:
Vector2 myVector = new Vector2(Vector2.Zero); //initialize to zero with copy constructor
I'm a little confused by Java's semantics here (i.e someVector essentially seems to be a pointer rather than an actual object, so I have to create a new object and explicity copy the values.) After reading up on that, I understand there's a lot of confusion on that topic. Is there a simple way to achieve the syntax I'm looking for or should I just stick with option 2? If there isn't, is there a way to prevent the assignment in option 1? It's going to give me some hard to catch errors later if I don't stop it at compile time.
Edit: Vector2 isn't immutable. What I'd like is for Vector2.ZERO to be a constant value I can use for assignments, but then manipulate those new variables normally. Right now if I do that assignment in multiple places, then all of those are just pointers to the same object (which because it's static just accumulates the changes).
For example, in Unity when working with vectors I would say something like:
Vector2 myFirstVector = Vector2.ZERO; //first vector, initialized to zero
...//do some stuff to change the value of myFirstVector, Vector2.ZERO unchanged
Vector2 mySecondVector = Vector2.ZERO; //second vector, also initialized to zero
...//do some stuff to mySecondVector
If you want your vectors to be mutable, having a static field that holds the zero vector is not a good choice (since it can mutate to something else later.
There are two approaches that you can take:
Mutable Vectors
public class Vector2 {
public static Vector2 Zero() {
return new Vector2(0,0);
}
}
Immutable vectors
public class Vector2 {
public static final Vector2 ZERO = new Vector2(0, 0);
private final int x;
private final int y;
public Vector2(int x, int y) {
this.x = x;
this.y = y;
}
public Vector2 add(Vector2 v) {
return new Vector2(this.x + v.x, this.y +v.y);
}
}
You may want to create a static factory method to return a new Vector that is Zeroed.
public class Vector2 {
public static Vector2 Zero() {
return new Vector2(0,0);
}
}
Then use it:
Vector2 myVector = Vector2.Zero();
Of course, if your default constructor initializes the vector to 0,0, then you may not need this and can simply do: Vector2 myVector = new Vector2();
Your initial thought about: "However, this behaves undesirably: myVector just becomes Vector2.ZERO--and thus unchangeable--" is incorrect unless Vector2 is immutable. You won't be able to reassign anything else to Vector2.ZERO, but you can certainly modify the object's contents.
Make your class immutable, so add() would return a new instance rather than modifying the instance, then:
myInstance = myInstance.add(myOtherVector);
See BigInteger for a class from the JDK that works like this.
That is the whole point of OOP and object references.
Vector2 myVector = Vector2.ZERO;
means that your myVector variable will reference to the same object (in memory) as static field Vector2.ZERO does. Basicly it is reffering the same object in memory.
You wrote:
someVector essentially seems to be a pointer
well, that is preatty it. References can be understood as pointers to objects just as pointers to defined memory address in C.
Related
Looks to me like primitive classes could behave more efficiently (at reasonable sizes) if they weren't immutable as currently proposed, but worked more like C structs.
Given this primitive class
primitive class Point implements Shape {
public long x;
public long y;
public Point(long x, long y) {
this.x = x;
this.y = y;
}
public boolean contains(Point p) {
return equals(p);
}
}
interface Shape {
boolean contains(Point p);
}
And an array Point[] points = new Point[N];
Why wouldn't we be able to do this?
points[0].x = 42; //lastore
points[1].x++; //laload, iinc, lastore
Point p = points[2]; //laload, laload
Shape s = p; //new Point.ref (boxing)
p.x++; //iinc
assert !s.contains(p);
Instead it sounds like current design intends for the whole Point be read, mutated using withfield and written back in its entirety, which seems kind of wasteful - especially for larger types. Or would compilers routinely apply copy elision here?
Note that Point must be flattened instead of flattenable here, so the user can be certain not to mutate a shared instance.
Could someone further clarify the rationale behind immutability of primitive types?
#see
JEP 401: Primitive Classes (Preview)
State of Valhalla - Part 3: The JVM Model
I'm writing a program that will need to use a limited set of Points to process an image. I figure that I would implement it as an immutable/singleton style class. Before going on to build more of the complex logic surrounding the class I wanted to get an opinion about the core class.
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.HashMap;
public class Point {
private final int x,y;
private final int hashCode;
private static final HashMap<int[],Point> points = new HashMap<>();
private Point(int x,int y){
this.x = x;
this.y = y;
this.hashCode = new HashCodeBuilder().append(x).append(y).toHashCode();
}
public static Point getPoint(int x,int y){
int [] candidate = new int[]{x,y};
if(points.containsKey((candidate))){
return points.get(candidate);
}
Point newPoint = new Point(x,y);
points.put(candidate, newPoint);
return newPoint;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public int hashCode(){
return hashCode;
}
#Override
public boolean equals(Object p){
return this == p;
}
}
I'm going to be using the class to do at least the following functions:
Map different channels in an image by this Point class
Define some static cached custom NavigableSets for ease of traversal
Various Helper functions. In example, get all Points surrounding a Point
Given the information provided, what are some downsides of the provided implementation?
Note: Putting the bulleted list before the code block breaks the display of the code block. Bug?
I think your caching "singletony" stuff may be pointless.
It doesn't save on object creation, as you will always create a candidate[] each time you ask for a Point. And, unless the Point gets reused, you use the memory for candidate and the Map.Entry in your HashMap. So, very roughly speaking, unless each Point gets reused three times, your caching uses more memory. And it always uses a more time.
If you don't cache, change your equals of course.
p.s. the rest seems fine, and immutable is good. You could consider making x and y public final to be more compatible with other Point implementations.
If you are worried about the occupied memory, there is another way to deal with it.
I assuming you have limited dimension for your points, I would suggest to combine your x & y in one variable of long (in case your dimensions is 32 ints long), or even int (if you can fit one dimensions in 16 bit), this way you'll get boost in performance & memory.
Other option is to use int[] array of your coordinates for a point, although that would take more space (since you would have to keep additional pointer reference).
Factory method in your implementation, will work only on single threaded applications, if you have multiple threads creating points, you would need to have some concurrency control in place. This would eat up your resources, because you would effectively need to lock on each point creation.
Another reason, why this Factory method is a bad idea, is that int[] arrays do not override equals and hashCode, you can try to create 2 arrays with same content, to check. So your HashMap would not simply work, and instead of saving memory you would not only create a new Point each time, but also add an entry to your HashMap and perform unnecessary calculations.
So either use Java primitives, or just create a new immutable Point each time if you need too, and go with it, don't overcomplicate with factoryMethods.
You had the right idea of making the Point class immutable but then you went and complicated things with the instance cache. It is not thread safe and it will leak memory because once a Point is created it will forever stay in the hashmap and will never be garbage collected.
Why not keep it simple and make a regular boring value class? Your IDE will even generate it for you.
Then, if you really really really want to have an instance cache, use Guava's Interner class instead of rolling your own. The result will look something like this:
public class Point {
final int x;
final int y;
private Point(int x, int y) {
this.x = x;
this.y = y;
}
static Interner<Point> instanceCache = Interners.newWeakInterner();
public static Point of(int x, int y) {
return instanceCache.intern(new Point(x,y));
}
public int getX() { return x; }
public int getY() { return y; }
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point other = (Point) o;
return this.x == other.x && this.y == other.y;
}
#Override
public int hashCode() { return x * 31 + y; }
}
I have an assignment I am working on where I have two classes.
Class A is called Points. It contains data for a 2D coordinate, and additional data associated to that specific point.
Class B is called Particles. It contains an array of objects of class A as well as some additional information.
I have a list of Particles. At initialization, all Particle objects contain an identical array of Points.
If I then change the value of the first position in the Points array in any Particle, I then see that all other Particles have mirrored this change. This is not the bahaviour I want. Instead, I want any changes in any Particle to be unique to that object.
public static class Particle{
public double[][] current = new double[NC][2];
public double[][] pBest = new double[NC][2];
public double[][] vel = new double[NC][2];
public Points[] points = new Points[array.length];
public double pbestfitness = 0.0;
public Particle(){
}
//standard get/set methods here
}
public static class Points{
public int x;
public int y;
public double centroidx;
public double centroidy;
public Points(){
this.x = -1;
this.y = -1;
this.centroidx = -1;
this.centroidy = -1;
}
public int getx(){
return x;
}
public void setx(int a){
x = a;
}
public int gety(){
return y;
}
public void sety(int a){
y = a;
}
public double getcx(){
return centroidx;
}
public void setcx(double a){
centroidx = a;
}
public double getcy(){
return centroidy;
}
public void setcy(double a){
centroidy = a;
}
}
initialization:
for(int i = 0; i < NP; i++){
p = new Particle();
initbest = new double[NC][2];
points = new Points[array.length];
points = array.clone();
for(int j = 0; j < NC; j++){
x = minx + r.nextInt(maxx - minx + 1);
y = miny + r.nextInt(maxy - miny + 1);
p.setCentroid(j, x, y);
initbest[j][0] = x;
initbest[j][1] = y;
}
p.setpBest(initbest);
p.setVel(initV);
p.points = points;
particles.add(p);
}
I thought that the issue was that I was copying each array of type A by address location rather than value, so I tried using System.arraycopy, and Arrays.copyOf() as well as array.clone, but none of them worked.
Here is code where I make a change to one object, but the change is mirrored in all objects:
particles.get(i).points[j].centroidx = particles.get(i).current[closest][0];
particles.get(i).points[j].centroidy = particles.get(i).current[closest][1];
The idea is basically I'm taking a set of point, adding a bunch of centroids, then finding which centroid is closest to each point and associating that point to that centroid. I run this with a set number of random starting positions, hence why I need to have a set number of copies of the starting positions represented by particles. I have ensured that the calculation for finding the closest centroid works using a testing data set of a low number of set points and centroids.
What happens after I complete an iteration of the first particle is that all the other particles are changed, when I have explicitly stated that the centroids of just the first particle is being changed. After the end of the first iteration of all particles is completed, all particles carry identical points arrays with centroids equivalent to the last copy that was changed. instead of unique points arrays with centroid data associated with that particle.
So the first particle will have a list of points with centroids that are not found to be a member of that particle. Instead, it holds the centroid data of the last particle of the previous iteration.
All the Point objects with same index reference the same object. So when you change one of them, all the other objects with the same index in all the arrays will change as well. You must make sure that on initialization you make a depp copy of all the Point objects. A deep copy means that the information (in fields) is all the same, but they refer to different objects (You must make a deep copy of the fields too). Arrays.copyOf will not help you because it will create a shallow copy (The points at the same index will refer to the same object.) You need to implement the clone method on point that will create a deep copy of the point. Then during initialization, just call point.clone().
See What is the difference between a deep copy and a shallow copy?.
I have a couple of suggestions.
First, when you describe a problem for which you provide code, refer to the variables/arrays/whatever with the names they have in the code. I don't know what you mean by A and B, and don't intend to dig through the code enough to guess, only to be wrong.
Second, if changing the data in one place automatically shows up in the other, then you almost certainly have a reference to the same object in the two places. If you do this:
A a = new A();
B b = new B();
b.setA(a);
array1[0] = a;
array2[0] = b;
then a change to a will be reflected in the object in both array1 and array2.
To prevent that, you can create an object of type A that is a copy of a, and put THAT into b before putting b into array2. Look up information on the Object.clone() method.
I would like to use different variables to access the same data.
i.e. I have an array:
float[] vector = new float[3];
I would like each value in the array to also have its individual label i.e.:
vector[0] == pitch;
vector[1] == yaw;
vector[2] == roll;
I would like to use vector[] & pitch/yaw/roll interchangeably. When I pass all three values between two functions I want to refer to the array, however when I access them individually I would like to refer to them as pitch yaw and roll.
Is this possible in Java?
This isn't possible the way you mean. You can't set pitch = 20 and get vector[0] == 20; primitives, at least, don't work that way in Java. What you could do, though -- what you should do -- is create a class named Vector with methods named setPitch, getPitch, etc, and use the float[3] as an internal implementation detail.
You can't do this with a primitive float and an array of type float[]. Java does not support variables that are pointers or references to primitives.
However, there are a few workarounds.
First, you could make your own mutable reference type holding a float value.
MyFloat[] vector = new MyFloat[3] { new MyFloat(p), new MyFloat(y), new MyFloat(r) };
MyFloat pitch = vector[0];
MyFloat yaw = vector[1];
MyFloat roll = vector[2];
But it would probably be better to wrap your array in an object, and use methods to get the members by meaningful name, rather than variables.
public class Orientation {
private float[] vector = new float[3];
public float[] getArray() { return vector; }
public pitch() { return vector[0]; }
public yaw() { return vector[1]; }
public roll() { return vector[2]; }
public setPitch( float pitch ) { vector[0] = pitch; }
public setYaw( float yaw ) { vector[1] = yaw; }
public setRoll( float roll ) { vector[3] = roll; }
}
This gets you close -- although you can't just say pitch, you could say o.pitch().
Passing a primitive data type in java only send a copy of its data to the requested method. If you are looking to pass a Reference to the value (rather than a copy), then you should use the Object form of the variables.
So, use Float in place of float. This will make your numbers Object variables rather than primitive data types.
public class NotActuallyImmutable {
private final int x;
public NotActuallyImmutable(int x) {
this.x = x;// line 1
}
public int getX() {
return x;
}
}
public class Mutable extends NotActuallyImmutable {
private int x = 123;
public Mutable(int x) {
super(x);
}
public int getX() {
return x++;
}
}
now in my main class
NotActuallyImmutable n = new Mutable(42); // line2
int x = n.getX();
System.out.println("x is"+x);
I am expecting the output as 42 but it return the output as 123. I am expecting 42 because at line 2 I am making object of class Mutable and then at line 1 I am setting value as 42. so when i do n.getX() I should get the this latest value not the default 123. I know Ii am missing something but not able to figure out the logic behind it?
The problem is that the field x in Mutable and the field x in class NotActuallyImmutable are not the same. The x that is returned by getX() is the one in Mutable (because the getX() that is invoked is Mutable.getX(), not NotActuallyImmutable.getX()).
Note that if you removed the instance field from Mutable, then you would have a compiler error because NotActuallyImmutable.x is private to NotActuallyImmutable and not accessible to any code in Mutable.
If you made NotActuallyImmutable.x a protected field, then Mutable.x would shadow it and you would still have the same behavior. If you removed Mutable.x in this case, you would still have a compiler error because you were trying to increment a final field.
If you remove Mutable.getX(), then the x that would be returned by getX() would be NotActuallyImmutable.x, despite there being another field of the same name in Mutable.
The private int x in Mutable and the private int x in NotActuallyImmutable are completely different fields that just have the same name.
This isn't a problem for the compiler because you can't access a private field from another class. So as far as the compiler is concerned, when you define Mutable, the x in NotActuallyImmutable is invisible and might as well not exist.
It is of course confusing for the programmer. If you rename one of the fields to y (and the getter method to getY) the behaviour seems much more intuitive.
NotActuallyImmutable n = new Mutable(42); // line2
This means you have an object of type NotActuallyImmutable but the instance of created object is Mutable.
so in this code your dealing with Mutable object which will return 123. as the number you passed is saved in NotActuallyImmutable not in Mutable,
n has two different x values which are visible in different contexts, the parent class's private member variable and the child class's private member variable.
NotActuallyImmutable n = new Mutable(42); // line2
Creates a new Mutable. Executes parent(x) which sets the parent class's x to 42.
int x = n.getX();
n is a Mutable instance so this calls Mutable's getX() which returns Mutable's value for x (123) rather than the parent's.
I agree with Nice explanations given in above answers. But to to just brief the final understanding. As i am doing new Mutable(42).getX(), jvm first will look in Mutable object to get the value of X not inside NotActuallyImmutable. If i remove getX() method from Mutable , i get the expected(as per my expectation) value i.e 42.
This example gets messy becoz variable name i.e X is same in parent and child class but good for understanding concept