I would like to have a static array in a Java class with an undetermined size initially. The intent is to use the array to store values calculated in a method in one class and used in another.
E.g. the 'TwoDX(Y)Pos[] arrays defined here:
public class DisplayObject {
// Each object is defined by a color, number of vertices, and dim (2,3,4) coordinate vertex locations
// Use dim to verify that the right number of vertices were sent
public static int Dim=3;
public static int RefDist=100;
public static int TwoDXpos[];
public static int TwoDYpos[];
}
And used here:
public void render2D(){
for (int cnt=0; cnt<this.NoOfVerts; cnt++){
if (this.coords[cnt*Dim+2] < RefDist) {break;}
TwoDXpos[cnt]=this.coords[cnt*Dim]/(this.coords[cnt*Dim+2]/RefDist);
TwoDYpos[cnt]=this.coords[cnt*Dim+1]/(this.coords[cnt*Dim+2]/RefDist);
}
}
But, since the original static references have no defined size, they reference Null pointers at execution.
How would you create such arrays?
I would like to have a static array in a java class with an initially undetermined size.
Sorry.
That isn't possible in Java. JLS-10.3. Array Creation says (in part)
The array's length is available as a final instance variable length.
Alternative
However, you could have a List of Foo(s) like
List<Foo> al = new ArrayList<>();
Use ArrayList instead of arrays.
Your code should look like this:
public class DisplayObject {
// Each object is defined by a color, number of vertices, and dim (2,3,4) coordinate vertex locations
// Use dim to verify that the right number of vertices were sent
public static int Dim=3;
public static int RefDist=100;
public static ArrayList<Integer> TwoDXPos;
public static ArrayList<Integer> TwoDYPos;
}
and the render 2d method:
public void render2D(){
for (int cnt=0; cnt<this.NoOfVerts; cnt++){
if (this.coords[cnt*Dim+2] < RefDist) {break;}
TwoDXpos.get(cnt)=this.coords[cnt*Dim]/(this.coords[cnt*Dim+2]/RefDist);
TwoDYpos.get(cnt)=this.coords[cnt*Dim+1]/(this.coords[cnt*Dim+2]/RefDist);
}
}
The advantage of using ArrayList is that you can use its add(item) method to change its size dynamically.
Hope it helps!
public void render2D() {
TwoDXpos = new int[this.NoOfVerts];
TwoDYpos = new int[this.NoOfVerts];
for (int cnt = 0; cnt < this.NoOfVerts; cnt++) {
if (this.coords[cnt * Dim + 2] < RefDist) {
break;
}
TwoDXpos[cnt] = this.coords[cnt * Dim] / (this.coords[cnt * Dim + 2] / RefDist);
TwoDYpos[cnt] = this.coords[cnt * Dim + 1] / (this.coords[cnt * Dim + 2] / RefDist);
}
}
and pls following Java naming rules to name your variable: http://www.iwombat.com/standards/JavaStyleGuide.html#Attribute%20and%20Local%20Variable%20Names
Short answer is you need to initialize the array before using them.
To avoid memory leakage, you should set its size at initialization. e.g.10.
public static int TwoDXpos[] = new int[10];
public static int TwoDYpos[] = new int[10];
If the array size changes, you should use ArrayList because its size is automatically managed by JVM
You can't use an array whose size is not determined. You should initialize the array size before method render2D() called. May be you could use this.NoOfVerts as the array size.
If you are going to use an array, you should initialize it by mentioning the size of the array in order to allocate memory before using it.
public static int TwoDXpos[];
public static int TwoDYpos[];
Any access on this would throw NullPointerException because the memory for this not allocated and object defintion has not happened at all.
You ought to remember this on array (or any objects for that sake) "Initialize before you access/use them"
If you worry is about that you are not sure about the number of elements upfront, you should use utilities like ArrayList which is provided in Java Collection Framework. This would take care dynamically adjusting the size as the number of elements increases.
Alternative Approach
private static List<Integer> twoDXPos = new ArrayList<Integer>();
private static List<Integer> twoDYPos = new ArrayList<Integer>();
and then itemes can be added using add method in java.util.Collection class. (Refer the link I gave above)
twoDXPos.add(1) //1 is an example integer here to illustrate
twoDYPos.add(1) //1 is an example integer here to illustrate
Related
I am wanting to make a method that can take in an array of n dimensions and then do some sorting with that info. The sorting part is out of the scope of this question though since the part I am stuck on is making a method accept an array of n dimensions. Normally you include something like int[] nums as a parameter. However, this does not allow for a scalable dimensional input. I did some research and the following code accurately calculates the dimensions of an array but I am not sure where to go from there since I cant figure out how to initialize an array of n dimensions from just an Object.
public static int dimensionOf(Object arr) {
int dimensionCount = 0;
Class<?> c = arr.getClass(); // getting the runtime class of an object
while (c.isArray()) { // check whether the object is an array
c = c.getComponentType(); // returns the class denoting the component type of the array
dimensionCount++;
}
return dimensionCount;
}
Here is something else to explain my issue lets say someone passes in a 2 dimensional array as the object. If that happened my dimensions variable would be equal to 2 since its using the above code to determine the dimension of the array. The thing I am stuck on is figuring out how to then produce a useable variable. Here you can see I tried to cast the object (which I know is an instance of array) to a 1d array which would through an error since the incoming object is a 2d array.
public static int sortNDimensionalArray(Object obj) {
int dimensions = dimensionOf(obj);
//This means we did not get an array passed in
if(dimensions == 0) return -1;
int[] array = (int[]) obj;
return 1;
}
I tried it out and got this and it works for me:
public static int dimensionOf(Object... args) {
int dim = 0;
Class<?> c = args.getClass();
while(c.isArray()) {
c = c.getComponentType();
dim++;
}
return dim;
}
I need to be able to have an n-dimensional field where n is based on an input to the constructor. But I'm not even sure if that's possible. Is it?
Quick solution: you could approximate it with a non-generic ArrayList of ArrayList of ... going as deep as you need to. However, this may get awkward to use pretty fast.
An alternative requiring more work could be to implement your own type using an underlying flat array representation where you calculate the indexing internally, and providing accessor methods with vararg parameters. I am not sure if it is fully workable, but may be worth a try...
Rough example (not tested, no overflow checking, error handling etc. but hopefully communicates the basic idea):
class NDimensionalArray {
private Object[] array; // internal representation of the N-dimensional array
private int[] dimensions; // dimensions of the array
private int[] multipliers; // used to calculate the index in the internal array
NDimensionalArray(int... dimensions) {
int arraySize = 1;
multipliers = new int[dimensions.length];
for (int idx = dimensions.length - 1; idx >= 0; idx--) {
multipliers[idx] = arraySize;
arraySize *= dimensions[idx];
}
array = new Object[arraySize];
this.dimensions = dimensions;
}
...
public Object get(int... indices) {
assert indices.length == dimensions.length;
int internalIndex = 0;
for (int idx = 0; idx < indices.length; idx++) {
internalIndex += indices[idx] * multipliers[idx];
}
return array[internalIndex];
}
...
}
Here's a nice article that explains how to use reflection to create arrays at run-time: Java Reflection: Arrays. That article explains how to create a one-dimensional array, but java.lang.reflect.Array also contains another newInstance method to create multi-dimensional arrays. For example:
int[] dimensions = { 10, 10, 10 }; // 3-dimensional array, 10 elements per dimension
Object myArray = Array.newInstance(String.class, dimensions); // 3D array of strings
Since the number of dimensions is not known until runtime, you can only handle the array as an Object and you must use the get and set methods of the Array class to manipulate the elements of the array.
Try this:
https://github.com/adamierymenko/hyperdrive
Situation (new in java):
I would like to store random values into an array of objects of a class i created.
I created the following class:
private double color;
private double size;
// default constructor
public Example() {
color = 0.0;
size = 0.0;
}
// second constructor taking two arguments
public Example(double color, size imaginary){
this.color=color;
this.size=size;
}
// mutators
public void setColor(double c){
color=c;
}
public void setSize(double s){
size=s;
}
Now in my driver class:
I created the following
import java.lang.Math;
int num = 4;
Example[] array;
array = new Example[num];
for(int i=0;i<num-2;i++)
{
randomColor = Math.random();
randomSize = Math.random();
array[i].setColor(randomColor);
array[i].setSize(randomSie);
}
When i run the program i get the following error message:
Exception in thread "main" java.lang.NullPointerException
Im assuming that the content in each element of the array is null. But why is that? and how do i make the logic above work ?
Obviously i want to stay within the boundaries of my knowledge which is around the complexity of this code.
Thank you
You have only created an array of Example objects, but every element of it is null since you haven't created any Example object instances.
Arrays of "reference types" (anything that is a class, interface, enum or array, basically) start out with having null references in every element, and you still need to create the objects to put in the array.
Change your code to :
array[i] = new Example(randomColor, randomSize);
which will create new Example objects, and assign the random values to its properties.
How is it possible to declare and initialize an array of constants in Java, without using enums ?
static final Type[] arrayOfConstants = new Type[10]; // not an array of constants
If you want to create an immutable array, no, you cannot. All arrays in Java are mutable.
If you just want to predefine the array in your class, you can do it:
private static final int[] MY_ARRAY = {10, 20, 30, 40, 50};
Here we created a predefined array MY_ARRAY of length 5, so MY_ARRAY[0] is 10 and so on. Be careful though as even the MY_ARRAY field is declared final, this does not mean that array elements could not be changed. Thus it's better not to expose such array to public via public or protected modifier.
If you don't want to modify the values, and you also just want to access the members of the collection without wanting random access, a very simple solution instead of having a constant array, have a final immutable list:
static final ImmutableList<Type> arrayOfConstants = ImmutableList.of(t1, t2, t3);
I mean the array components be constants i.e. a[0] be a constant variable like this public static final int SIZE = 10;
You cannot give array indexes names.
You could initialize an array using the values of pre-existing constants:
public static final int SIZE = 10;
public static final int[] CONSTANTS = { SIZE };
Keep in mind that although an array is declared final, it's values may still be changed. final only ensures you cannot re-assign the array variable, so you will want to encapsulate the array to prevent mutation:
final class Constants {
public static final int SIZE = 10;
private static final int[] CONSTANTS = { SIZE };
public static int getConstant(int index) {
return CONSTANTS[index];
}
}
If you would like to loop, I suggest returning a deep-copy of the array.
if final is used with objects you cannot change the reference of that object but changing the value is perfectly fine.Array is an object in java and if you want object value should not be changed, once created, then you will have to make object immutable and primitive array cannot be made immutable in java.
final int [] finalArr={5,6,8};
System.out.println("Value at index 0 is "+finalArr[0]);
//output : Value at index 0 is 5
//perfectly fine
finalArr[0]=41;
System.out.println("Changed value at index 0 is "+finalArr[0]);
//Changed value at index 0 is 41
int[] anotherArr={7,9,6};
// finalArr=anotherArr;
//error : cannot assign a value to final variable finalArr
For more on immutable array you can refer to these links:
Immutable array in Java
Is there any way to make an ordinary array immutable in Java?
-If you know the values before-hand, initialize the array values and mark that array as final.
-If you don't know the values initially then write public getter/setters methods and declare the array as private. Write logic in setter method to discard changes once done on a particular element (or throw an exception upon multiple changes to the same element)
Its'been a while this post is open
I am surprised, why any one would not think of
public static final List<LanguageModel> GenderDataSource = new ArrayList<GenderModel>(){{
add(new LanguageModel("0", "English"));
add(new LanguageModel("1", "Hindi"));
add(new LanguageModel("1", "Tamil"));
};};
Where LanguageModel simply contains two properties Id and Title or use whatever your model class of generic Type could be.
Should work great as constant.
-- N Baua
I saw this post and it made me think about something I did for a chess playing application.
Maybe you just want a group of constants that are sons of another constant. I mean, if you make a final class named as your "array", and inside it you describe several constants, you'll be able to access it via MyClass.MYARRAY.MYCONSTANT.
The code would be:
abstract class Figure {
public static final class WEIGHT{
public static final int PAWN = 1;
public static final int KNIGHT = 3;
public static final int BISHOP = 3;
public static final int ROCK = 5;
public static final int QUEEN = 10;
public static final int KING = 1000;
}
}
public class Pawn extends Figure{
public static final int weight = Figure.WEIGHT.PAWN;
}
I don't know if it is the best way for doing it. I don't either know if it's the worst way. But I think it answers your question and gives you a solution.
I'm doing a task for a course in Java programming and I'm not sure how the following thing is working? The method below takes the value from an array and a integer. The integer should be added to the array and then be used outside the method in other methods and so on, but how could this work when the method has no return for the new content of the array? There is a void in the method? Have I missed something? Preciate some help? Is there something about pointers?
public static void makeTransaction(int[] trans, int amount);
Arrays in Java are objects. If you modify the trans array inside the method, the changes will be reflected outside of it1. Eg:
public static void modify(int[] arr)
{
arr[0] = 10;
}
public static void main(...)
{
int x = {1, 2, 3};
System.out.println(x[0]); // prints 1
modify(x);
System.out.println(x[0]); // now it prints 10
}
Note that native arrays can't be dynamically resized in Java. You will have to use something like ArrayList if you need to do that. Alternatively you can change the return type to int[] and return a new array with the new element "appended" to the old array:
public static int[] makeTransaction(int[] trans, int amount)
{
int[] new_trans = Arrays.copyOf(trans, trans.length + 1);
new_trans[trans.length] = amount;
return new_trans;
}
1 It is also worth noting that as objects, array references are passed by value, so the following code has no effect whatsoever outside of the method:
public void no_change(int[] arr)
{
arr = new int[arr.length];
}
You can't add anything to an array. Java arrays have a fixed length. So indeed, what you want to do is impossible. You might make the method return an int[] array, but it would be a whole new array, containing all the elements of the initial one + the amount passed as argument.
If you want to add something to an array-like structure, use an ArrayList<Integer>.
Do you have to keep the method signature as is?
Also, can you be a bit more specific. When you say "the integer should be added to the array", are you referring to the amount argument? If so, then how is that amount added? Do we place it somewhere in the array or is it placed at the end, thus extending the array's length?
As far as pointers go, Java's pointers are implicit, so if you don't have a strong enough knowledge of the language, then it might not be so clear to you. Anyways, I believe that Java methods usually will pass objects by reference, and primitives by value. But, even that isn't entirely true. If you were to assign your object argument to new object, when the method terminates, the variable that you passed to the method is the same after the method executed as it was before. But, if you were to change the argument's member attributes, then when the method terminated those attributes values will be the same as they were inside of the method.
Anyways, back to your question, I believe that will work because an array is an object. So, if you were to do the following:
public static void makeTransaction(int[] trans, int amount)
{
trans[0] = amount;
}
// static int i;
/**
* #param args
*/
public static void main(String[] args)
{
int[] trans = {0,1,3};
makeTransaction(trans, 10);
for(int i = 0; i<trans.length; i++)
{
System.out.println(trans[i]);
}
}
The output of the array will be:
10
1
3
But, watch this. What if I decided to implement makeTransaction like so:
public static void makeTransaction(int[] trans, int amount)
{
trans[0] = amount;
trans = new int[3];
}
What do you think that the output will be? Will it be set to all zero's or will be the same as it was before? The answer is that the output will be the same as it was before. This ties in to what I was saying earlier.
I might've assigned that pointer to a new object in memory, but your copy of the pointer inside of the main method remains the same. It still points to the same place in memory as it did before. When the makeTransaction method terminates, the new int[3] object that I created inside of it is available for garbage collection. The original array remains intact. So, when people say that Java passes objects by reference, it's really more like passing objects' references by value.