How do you (get around) dynamically naming variables? - java

I'm not sure if I'm using the right nomenclature, so I'll try to make my question as specific as possible. That said, I imagine this problem comes up all the time, and there are probably several different ways to deal with it.
Let's say I have an array (vector) called main of 1000 random years between 1980 and 2000 and that I want to make 20 separate arrays (vectors) out of it. These arrays would be named array1980, array1981, etc., would also have length 1000 but would contain 1s where the index in the name was equal to the corresponding element in main and 0s elsewhere. In other words:
for(int i=0; i<1000; i++){
if(main[i]==1980){
array1980[i]=1;
} else {
array1980[i]=0;
}
Of course, I don't want to have to write twenty of these, so it'd be good if I could create new variable names inside a loop. The problem is that you can't generally assign variable names to expressions with operators, e.g.,
String("array"+ j)=... # returns an error
I'm currently using Matlab the most, but I can also do a little in Java, c++ and python, and I'm trying to get an idea for how people go about solving this problem in general. Ideally, I'd like to be able to manipulate the individual variables (or sub-arrays) in some way that the year remains in the variable name (or array index) to reduce the chance for error and to make things easier to deal with in general.
I'd appreciate any help.

boolean main[][] = new boolean[1000][20];
for (int i=0; i < 1000; i++) {
array[i][main[i]-1980] = true;
}
In many cases a map will be a good solution, but here you could use a 2-dim array of booleans, since the size is known before (0-20) and continuous, and numerable.
Some languages will initialize an array of booleans to false for every element, so you would just need to set the values to true, to which main[i] points.
since main[i] returns numbers from 1980 to 2000, 1980-main[i] will return 1980-1980=0 to 2000-1980=20. To find your values, you have to add 1980 to the second index, of course.

The general solution to this is to not create variables with dynamic names, but to instead create a map. Exactly how that's done will vary by language.
For Java, it's worth looking at the map section of the Sun collections tutorial for a start.

Don Roby's answer is correct, but i would like to complete it.
You can use maps for this purpose, and it would look something like this:
Map<Integer,ArrayList<Integer>> yearMap = new HashMap<Integer,ArrayList<Integer>>();
yearMap.put(1980,new ArrayList<Integer>());
for (int i = 0; i < 1000; i++){
yearMap.get(1980).add(0);
}
yearMap.get(1980).set(999,1);
System.out.println(yearMap.get(1980).get(999));
But there is probably a better way to solve the problem that you have. You should not ask how to use X to solve Y, but how to solve Y.
So, what is it, that you are trying to solve?

Related

Selection of Array depending on variable in Java

I am sure that this post silly, while I need still some practical ideas. I have 20 double[] arrays named like colVal1, colVal2,... Now I have 5 variables say que1, que2, que3, que4, que5 which contain integers from 1 to 20. I want to use arrays depending on the value contained in quei. Means if que1 contains 3 then I like to use colval3 in calculation. Manual use is avoidable due permutations of 20 numbers in 5 variables. Google hints that Java, in principle avoid replacement of variable name by another variable. I am lost at using HashMap. I could not use Reflection APIs correctly due to my limited knowledge base. Any handle is welcome.
Thanks and Regards
You know how to use an array I assume, so use an array of arrays.
double[][] colVal = new double[21][];
for (int i = 1; i <= 20; i++) {
double[] row = colVal[i];
System.out.println(Arrays.toString(row));
}
Note: this might be simpler if you started at 0 for the first row, instead of 1. i.e. you wouldn't need the unused row at the start.

How do you create a mathematical sequence in Java?

I want to declare integers, while the program is running.
I run the program, and then I give it via System.in.println an integer and repeat this as long as I want.
I want the program to give those integers a name of a certain type for, for example a(i) or a[i], dunno, (it should be handy) and then a(i) represents the the i'th integer I gave the program.
My idea is then that I can use those elements by their name just like, if I had declared them in the first place.
For example add two integers together.
For example I defined a method add+, which waits for 2 integer and then adds them. For example I write:
add
a(2)
a(47)
(then I would get here the result.)
I don't think implementing the add function is difficult. However I don't know, how to let the program count the number of inputs or how to let it declare and use variables.
First: Welcome to programming java; it will be a long road.
Here are some hints:
Use a List<Integer> to hold the sequence of numbers entered by the user.
Actually instanciate a concreate List class, for example LinkedList<Integer>'. If you need to access the elements by index, use anArrayList`.\
Each time the user enters a number, create a new Integer and userList.add(newInteger);
Simple sample
List<Integer> userList = new LinkedList<Integer>();
for (index = 0; index < 9; ++index)
{
Integer newInteger = new Integer(index);
userList.add(newInteger);
}
for (Integer current : userList)
{
System.out.println(current);
}
Yeah, I am following the conversation.
I am just a bit frustrated, because I can't really write any interesting or practical java programs (yet), because my knowledge isn't that big yet.
First I tried to find out, if there was a way to add elements to array, because arrays seemed to me very useful, because each element of an array already has an address. I googled, and it seems that is not possible.
I might be able to use the idea with the list, but it seems to be that the length of the list has to have a limit and actually I wanted to avoid that.

Multidimensional arrays with different sizes

I just had an idea to test something out and it worked:
String[][] arr = new String[4][4];
arr[2] = new String[5];
for(int i = 0; i < arr.length; i++)
{
System.out.println(arr[i].length);
}
The output obviously is:
4
4
5
4
So my questions are:
Is this good or bad style of coding?
What could this be good for?
And most of all, is there a way to create such a construct in the declaration itself?
Also... why is it even possible to do?
Is this good or bad style of coding?
Like anything, it depends on the situation. There are situations where jagged arrays (as they are called) are in fact appropriate.
What could this be good for?
Well, for storing data sets with different lengths in one array. For instance, if we had the strings "hello" and "goodbye", we might want to store their character arrays in one structure. These char arrays have different lengths, so we would use a jagged array.
And most of all, is there a way to create such a construct in the declaration itself?
Yes:
char[][] x = {{'h','e','l','l','o'},
{'g','o','o','d','b','y','e'}};
Also... why is it even possible to do?
Because it is allowed by the Java Language Specification, ยง10.6.
This is a fine style of coding, there's nothing wrong with it. I've created jagged arrays myself for different problems in the past.
This is good because you might need to store data in this way. Data stored this way would allow you to saves memory. It would be a natural way to map items more efficiently in certain scenarios.
In a single line, without explicitly populating the array? No. This is the closest thing I can think of.
int[][] test = new int[10][];
test[0] = new int[100];
test[1] = new int[500];
This would allow you to populate the rows with arrays of different lengths. I prefer this approach to populating with values like so:
int[][] test = new int[][]{{1,2,3},{4},{5,6,7}};
Because it is more readable, and practical to type when dealing with large ragged arrays.
Its possible to do for the reasons given in 2. People have valid reasons for needing ragged arrays, so the creators of the language gave us a way to do it.
(1) While nothing is technically/functionally/syntactically wrong with it, I would say it is bad coding style because it breaks the assumption provided by the initialization of the object (String[4][4]). This, ultimately, is up to user preference; if you're the only one reading it, and you know exactly what you're doing, it would be fine. If other people share/use your code, it adds confusion.
(2) The only concept I could think of is if you had multiple arrays to be read in, but didn't know the size of them beforehand. However, it would make more sense to use ArrayList<String> in that case, unless the added overhead was a serious matter.
(3) I'm not sure what you're asking about here. Do you mean, can you somehow specify individual array lengths in that initial declaration? The answer to that is no.
(4) Its possible to extend and shrink primitive array lengths because behind the scenes, you're just allocating and releasing chunks of memory.

Array iteration with static final limits

I have an array:
final int[] exampleArray = new int[ID_DATA_ARRAY_SIZE];
And I can iterate that array several ways, for example:
Way 1:
for (int i = 0; i < exampleArray.length; i++) {
// code where I use 'i' index
}
Way 2:
for (int i = 0; i < ID_DATA_ARRAY_SIZE; i++) {
// code where I use 'i' index
}
Which way is better? Are there any other better ways to do it?
If you don't need i for anything else than extracting the element, then the enhanced for loop looks a bit nicer:
for(int element : exampleArray) {
//code that uses element
}
If you are using i for both accessing the array, and something else, then I would argue Way 1 is best:
for (int i = 0; i < exampleArray.length; i++) {
// code where I use 'i' index
}
The reason is that the next time someone looks at a code, the person will immediately see that you are iterating to the length of the array. If you go for way 2 (using a constant), the reader might wonder if that constant really is the length of your array.
Tackling both performance, and code readability, way 2 is better.
Rated by performance, by using exampleArray.length you are calling upon a "member" variable which requires additional java bytecode to request when compared to calling a "local" variable. But, the difference in performance is extremely minuscule and you would never notice it unless you were making an extreme amount of calculations.
Rated by readability, ID_DATA_ARRAY_SIZE lays out your intent for whomever is reading, which is more important than it may seem. Yet, too many programmers lay out nonsensical or ambiguous variable names, and it makes reading their code lacking in naturalness. Naming variables and functions in a way that makes sense to our minds in an organic way makes the code much simpler to deal with for yourself in the future, and anyone else, making it a good practice.
The fundamental difference in the two approaches, I see is as below:
In Way 1: you use the constant exampleArray.length in the loop condition
In Way 2: you use the constant ID_DATA_ARRAY_SIZE in the loop condition
Obviously way 2 is superior in terms of performance.
This is because you are accessing a constant rather than access member variable of exampleArray object. This advantage is realized in every iteration of the for loop where the value of length member is accessed.
see it is all about personal taste which way you wanna do but whenever you are working with array better to check null for the array and then do your stuff

Java: Sorting different types of arrays to one another

I need to sort an array based on the positions held in another array.
What I have works, but it is kinda slow, is there a faster/better way to implement this?
2 Parts:
Part1
int i = mArrayName.size();
int temp = 0;
for(int j=0;j<i;j++){
temp = mArrayPosition.get(j);
mArrayName.set(temp, mArrayNameOriginal.get(j));
}
In this part, mArrayPosition is the position I would like the mArrayName to be in.
Ex.
input:
mArrayName= (one, two, three)
mArrayPosition = (2,0,1)
output:
mArrayName= (three, one two)
Part 2
int k=0;
int j=0;
do{
if(mArrayName.get(k)!=mArrayNameOriginal.get(j)){
j++;
}else{
mArrayIdNewOrder.set(k, mArrayId.get(j));
k++;
j=0;
}
}while(k < mArrayName.size());
}
In this part, mArrayName is the reordered name array, mArrayNameOriginal is the original name array.
Ex.
mArrayName = (three, one, two)
mArrayNameOriginal = (one, two, three)
Now I want to compare these two arrays, find which entries are equal and relate that to a new array that has their rowId number in it.
Ex.
input:
mArrayId = (001,002,003)
output:
mArrayIdNewOrder = (003,001,002)
So then I will have mArrayIdNewOrder id's matching up with the correct names in mArrayName.
Like I said these methods work, but is there a faster/better way to do it? I tried looking at Arrays.sort and comparators but they only seem to sort alphabetically or numerically. I saw something like I can create my own rules inside the comparator but it would probably end up being similar to what I already have.
Sorry for the confusing question. I'll try to clear up any ambiguities if needed.
The best performance read I've found is Android's Designing For Performance doc. You are violating a couple of the "Android way" style of doing things that will help you.
You are using multiple internal getters inside each loop for what looks like a simple value. Redo this by accessing the fields directly.
For extra credit, post your performance comparison results! I'd love to see em!
You could use some form of tuple, some class to hold both id and name. You'll just to have a java.util.Comparator that compares it accordingly, both elements will move together and your code will be cleaner.
This data structure might be convenient for the rest of your program... if not, just take things off it again and you're done.
If your order indexes are compact, i.e. from index 0 to size - 1, then just use an array and create the updated list afterwards? About something like
MyArray[] array = new MyArray[size];
for(int j=0;j< size;j++) {
array[ mArrayPosition.get(j) ] = mArrayName.get(j);
}
// create ArrayList from array

Categories