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.
Related
If I have a function that takes a double as an argument, I can easily put in a float.
However when I have a funcion that takes a double[] then I cannot pass a float[].
public static void doSomethingWithMyDoubles(double[] doubles) {
//....
}
public static void doSomethingWithMyDouble(double doubles) {
//....
}
public static void main() {
float floater = 10f;
double doubler = 10d;
doSomethingWithMyDouble(doubler) // OK
doSomethingWithMyDouble(floater) // OK
float[] floates = new float[10];
double[] doubles = new double[10];
doSomethingWithMyDoubles(doubles) // OK
doSomethingWithMyDoubles(floates) // NOK
}
In Java, arrays are not a primitive data type; instead they are of type Object. As a consequence, you cannot convert an array of one primitive type to an array of another primitive type directly (even though you might cast the individual elements in the array to the other type).
It is because implicite type conversion takes place when you pass float value into the method whitch requires double one. But there is no type conversion between float[] and double[] arrays.
A float is a 4-byte type, and a double is an 8-byte type. Widening a single float to a double is a constant-time operation. However, widening a float[] to a double[] has to do a full copy, and needs to take linear time to widen the entire array. So Java won't do it implicitly -- it won't pretend that the operation is as cheap as an O(1) operation.
That is because float and doubles are primitives. Floats can be automatically casted into doubles. However, double[] and float[] are objects. Try explicitly casting. You may need to iterate and cast each element and insert into your new array.
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'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.
Lets say this is the C++ code:
void change(int& x){
x++;
}
or
void change2(int* a){
*a++;
}
Both will change the global x, right?
So how can I do something like that in java?
Specifically, I want to point to a Vector object
But since Java has no pointers, I'm not sure what to do.
From searching the internet I saw people saying that Java does that in some other way, but I haven't found any real example.
Thanks for
help!
In Java, instead of pointers you have references to objects. You cannot pass a primitive type by reference, but you can wrap a primitive type inside an object and then pass a reference to that object.
Java provides the type Integer which wraps int, however this type is immutable so you cannot change its value after construction. You could however use MutableInt from Apache Commons:
void change(MutableInt x) {
x.increment();
}
The change to x will be visible to the caller.
Specifically, I want to point to a Vector object
When you write Vector v = ...; you are assigning a reference to a vector to the variable v. A reference in Java is very similar to a pointer. References are in fact implemented internally using pointers.
Java uses pass by value. When you pass a vector to a method, you are actually copying a reference to that vector. It does not clone the vector itself. So passing a reference in Java is very similar to passing a pointer in C++.
With Java you cannot pass primitive types like int by reference, they are passed only by value.
The only things you can do is to find artifices to do that, because instead Objects are passed by reference. Here two examples.
Use an array of single value, like this
int[] value = new int[1];
value[0] = 2;
// call a method
obj.setValue(value);
// and in setValue
public void setValue(int[] value) {
value[0] = 5;
}
Or second approach use an holder class:
public class Holder<T> {
public T value;
public Holder(T value) {
this.value = value;
}
}
// then use it in this way
Holder<Integer> h = new Holder<Integer>(2);
obj.setValue(h);
// and in setValue
public void setValue(Holder<Integer> h) {
h.value = 5;
}
In this case I use an holder class implements with generics but you can have a simple holder too, only for integer. For example:
public class IntHolder {
public int value;
public IntHolder(int value) {
this.value = value;
}
}
Java always passes by value and there are no global variables as in the C++ sense. So if you want to do the same as in C++ you need to return the new value.
Thusly:
public int change(int x) {
return ++x;
// or
// return x + 1;
}
To test it:
int x = 2;
change(x);
System.out.println(x); // returns 2
x = change(x);
System.out.println(x); // returns 3
So it doesn't make any sense to let the method be called change, it is more sensible along the lines of calculateThisInt.
Java does pass objects by value. But as Mark Byers mentions the Integer class is immutable and you could use MutableInt from Apache Commons library. To describe how this works you could implement it yourself for your example:
public class MyInt() {
public int i;
public void setInt(int i) {
this.i = i;
}
public int getInt() {
return this.i;
}
public int increment() {
this.i++;
}
}
You need to change your change function to have the above MyInt object as argument:
public void change(MyInt i) {
i.increment();
}
Usage:
MyInt x = new MyInt();
x.setInt(2);
change(x);
System.out.println(x.getInt); // returns 3
In your case you want to change a Vector object...
public void changeVector(Vector v) {
// anything you do with 'v' will change it even
// for the scope that called this method
}
// Usage:
Vector v = new Vector();
changeVector(v);
// v should be changed after calling change vector method
Hope this all makes sense.
Both will change the global x, right?
So how can I do something like that in java? Specifically, I want to
point to a Vector object
The question is somewhat vague, but I got the impression that you ultimately want a global Vector that you can keep stuff in?
Many ways to do that, but one of the simplest is to have a static field in a class, with public static methods for accessing it. (Or simply a public static field which is accessed directly, but that really wouldn't be idiomatic in Java.)
public class Foo {
private static List<Integer> globalVector = new Vector<Integer>();
public static void add(int number){
globalVector.add(number);
}
// ... plus whatever other accessors to the global list that you need
}
Anywhere else in code:
Foo.add(23); // modifies the global vector
(Btw, Vector is kinda obsolete, and typically we'd use ArrayList in its place now. As the Javadoc says, it's been retrofitted to implement the List interface, which I also used in the example.)
While you can't replace an object that's been passed to a function, you can change its state by altering fields directly or calling methods. If you need something like a pointer to a primitive, wrap it in an object. To follow your code, you could do this:
public class IntPointer {
public int value;
public IntPointer(int value) {
this.value = value;
}
}
Then elsewhere you could say:
public static void change(IntPointer ipoint) {
ipoint.value++;
}
public static void main(String[] args) {
IntPointer a = new IntPointer(10);
change(a);
}
This might seem a bit awkward, but it hasn't come up for me as often as you'd think. I'd be more likely to do something like this:
public class ABPair {
private int a = 0;
private int b = 0;
public static void changeA() {
a++;
}
public static void changeB() {
b++;
}
}
So that elsewhere I can say:
public static void main(String[] args) {
ABPair ab = new ABPair();
if (ACondition) {
ab.changeA();
}
}
In other words, my data tends to already be wrapped in some sort of object, and I tend to use the data object's methods to mediate any changes.
Java supports what it calls "references". References act alot like pointers in C/C++-like languages. They don't act the same way "references" work in those languages.
The major differences between a pointer in C and a reference in Java are:
You can't do pointer arithmetic in Java (i.e. you can't "add" or "subtract" from a Java reference, you can only dereference it or compare it with another one).
You can't cast it to an incompatible type: Java is strongly type-safe, you can't "re-interpret" the bytes in memory as some other object.
For some uses of pointers this has no real effect (for example linked lists work pretty much the same in both languages), for others the difference is quite major (arrays in C are just fancy pointer arithmetic, in Java they work quite differently).
So in a way Java references could be called "restricted pointers".
I know that with the following, a reference is made
public class MyClass
{
public Integer value;
}
public class Main
{
public static void main( String[] args )
{
MyClass john = new MyClass();
john.value = 10;
MyClass bob = john;
bob.value = 20;
System.out.println(Integer.toString(john.value)); // Should print value of "20"
}
}
But how do you do similar referencing with primitive data-types?
public class Main
{
public static void main( String[] args )
{
Integer x = 30;
Integer y = x;
y = 40;
System.out.println(Integer.toString(x)); // Prints "30". I want it to print "40"
}
}
Simple answer: you don't. Primitive values are always passed by value (i.e. they are copied).
Wrapper objects like Integer are also immutable, i.e. y = 40 will create a new Integer object with the value 40 and assign it to y.
To achieve what you want you need a container object whose value you can change.
You could, for example, use AtomicInteger:
AtomicInteger x = new AtomicInteger(30);
AtomicInteger y = x;
y.set( 40 );
System.out.println(x.get());
You cannot. While Integer is not a primitive datatype but a wrapper class around the int primitive type, your code is equivalent to:
Integer y = x;
y = new Integer(40);
So you are actually changing the object y points to. This mechanism is called auto-boxing. There's a simple rule of thumb: in order to change the state of an object, rather than to replace the whole object, you have to call one of your object's methods. It's quite common for classes representing values, such as numbers, not to provide such methods, but to require that the object be replaced by a new one representing the new value.
What happens in your second code block is that 30 gets boxed into an Integer and assigned to x. Then you assign that same Integer to y. x and y are now pointing to the same object. But when you do y = 40, that 40 is boxed into a new Integer object and gets assigned to y. The Integer class is immutable, you won't be able to change its value after creation.