I created a very simple program to create an ArrayList of 2 Dimensional arrays of floats.
But adding new elements in the list seems to overwrite or corrupt previous elements.
What am i doing wrong and how should this functionality be implemented?
import java.util.ArrayList;
public class multiDArrayTest {
public static void main(String[] args) {
float[][] coeff = new float[3][6];
ArrayList<float[][]> basisCoeffs;
basisCoeffs = new ArrayList<float [][]>(2);
coeff[0][0] = 0;
coeff[0][1] = 100;
coeff[0][2] = -50;
basisCoeffs.add(coeff);
coeff[0][0] = 50;
coeff[0][1] = 200;
coeff[0][2] = -400;
basisCoeffs.add(coeff);
System.out.println(basisCoeffs.get(0)[0][0]);
System.out.println(basisCoeffs.get(0)[0][1]);
System.out.println(basisCoeffs.get(0)[0][2]);
//I should get 0 100 -50 50, but i don't? Where does it go ??
System.out.println(basisCoeffs.get(1)[0][0]);
System.out.println(basisCoeffs.get(1)[0][1]);
System.out.println(basisCoeffs.get(1)[0][2]);
}
}
Here you add the array to the ArrayList, you modify that array, then you add it to the ArrayList a second time. So you have two copies of the same array in the ArrayList. I think you are confusing primitives and objects here. Arrays are objects, so they can be modified. When you get the elements out of the ArrayList, you see both elements point to that same array, which you modified, so you get the modified values back out. If you don't want that behavior, just clone the array when you add it to the ArrayList. Something like basicCoeffs.add(coeff.clone());.
What happens is that you have the coeff array with the first values, you add it to the list and everything is fine, but when you edit coeff again before adding it to the list, you also edit the one that is in position 0 of the list, since both coeff as the element in position 0 of the list they refer to the same object in Java. One option would be to create a copy and another to have the two arrays separately. Also, since I observe that your dimensions are static, you can directly add the values to the designated positions, for example:
import java.util.ArrayList;
public class multiDArrayTest {
public static void main(String[] args) {
ArrayList<float[][]> basisCoeffs = new ArrayList<float [][]>(2);
basisCoeffs.add(new float[3][6]);
basisCoeffs.add(new float[3][6]);
// First values of coeffs
basisCoeffs.get(0)[0][0] = 0;
basisCoeffs.get(0)[0][1] = 100;
basisCoeffs.get(0)[0][2] = -50;
// Second values of coeffs
basisCoeffs.get(1)[0][0] = 50;
basisCoeffs.get(1)[0][1] = 200;
basisCoeffs.get(1)[0][2] = -400;
System.out.println(basisCoeffs.get(0)[0][0]);
System.out.println(basisCoeffs.get(0)[0][1]);
System.out.println(basisCoeffs.get(0)[0][2]);
System.out.println(basisCoeffs.get(1)[0][0]);
System.out.println(basisCoeffs.get(1)[0][1]);
System.out.println(basisCoeffs.get(1)[0][2]);
}
}
Arrays in java are Mutable and pass by reference (well, pass by value of reference). this means is you change an element in an array, the reference is changed. So what do we have to do to avoid these side effects?
You can encapsulate Lists and arrays and just add a copy of objects into arrays.
if you're using Java 9 or later you can use List<float[][]> basisCoeffs = List.of(coeff) to add its Item as an immutable list.
you can read more about mutables and immutables here: Immutable class?
Related
I want to save the steps pf my player-character in a Sokoban-game.
So at first i want to fill an Array of int x and y, called "pos" with the actual position of the character.
And than i want to add this array to an ArrayList of Arrays, called "moves".
Array for one player-position:
int[] pos = new int [2];
ArrayList for all steps, the player made in the level:
Arraylist<Integer[]> moves = new ArrayList<>();
"int[]" makes an error, if placed inside the pointy brackets at the ArrayList.
How do i add the Array pos to the ArrayList moves?
This works completely fine with int[]. However int[] != Integer[], Use same in both places.
int[] pos = new int[2];
ArrayList<int[]> arrayList = new ArrayList<>();
pos[0] = 1;
pos[1] = 2;
arrayList.add(pos);
System.out.println(arrayList.get(0)[0]+ " "+ arrayList.get(0)[1]);
int and Integer are two different things (I struggled with this as well when I first learned Java a long time ago.
int is a so-called primitive datatype, which means it is not an object. Integer is a wrapper class, basically a class whose only purpose is to contain an
int so that it can be handled as an object. Since Java 5, there is "autoboxing", which means you can assign int values to Integer variables and vice versa, and the compiler will handle it silently. This tends to muddle the difference, but it still is there and important - such as in this case.
So if you want to store instances of int[] in an ArrayList, you need an ArrayList<int[]>, not an ArrayList<Integer[]>.
However, it is impossible to have an ArrayList<int> because ArrayList can only store Objects (the generic types exist only for the compiler), not primitives.
Oh yes, and to add an element to the list, use
Arraylist<int[]> moves = new ArrayList<>();
arrayList.add(pos);
You could have found this in the API doc for ArrayList - you should really learn to use the API doc, you will need it all the time to answer questions such as this.
You can also make class (for example Pos) and make x and y as attributes and make constructor. The you can make the type of arraylist is Pos
ArrayList arrayList = new ArrayList<>();
arrayList.add(new Pos(3,2));
I am writing a program that will take input of polynomials. Needing to create a new ArrayList for each polynomial input, I am needing a way to name each list without knowing the amount of polynomial beforehand. If a file has 2 polynomials I will need to name 2 arrays, but if more polynomials I will need to name more arrays. Is there anyway to automatically name arrays or variables with the iteration of a loop. I cannot figure out how. Variable names such as : P1 , P2, P3 etc. as the number of Polynomials increases is what I am searching for. Each polynomial will be read in line by line. I have attached my code, Though it is nowhere near complete. I imagine I will need to move the PolyCalc creation into the while loop and create a new PolyCalc for each line of input. I am looking to add this feature to the while loop in the main method.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class PolyProcessor {
static int polyNum = 0;
public static void main(String[] args) throws FileNotFoundException{
File polyfile = new File("polyinput.txt");
Scanner read = new Scanner(polyfile);
while (read.hasNextLine()){
PolyCalc c = new PolyCalc();
String j = read.nextLine();
c.add(j.split(";"));
polyNum++;}
}
}
class PolyCalc{
static int polyCount = 0;
static ArrayList polynomials = new ArrayList();
static void add(String[] strings){
for(int i = 0; i<strings.length;i++){
polynomials.add(strings[i]);
polyCount++;}
}
static Object get(int i){
return polynomials.get(i);
}
}
Why not use a (Hash) Map where the key is the variable name?
Map polys = new HashMap();
int count=0;
For ...
string key = String.format("p%02d",count++);
polys.put(key, newPoly(...));
I'd have to look up the String.format but something like that.
The order needs to be preserved so just choose long enough zero padded keys that you can sort. And/or use a linkedHashMap which keeps the insertion order.
As Stephen's answer and you said that arraylist is mandatory you could still use ArrayList
ArrayList numbers = new ArrayList();
HashMap<String,ArrayList> myPolys = new HashMap<String,ArrayList>();
and to use the HashMap
myPolys.put(what do you want to call them or your so "called" variables , numbers);
First of all, you can't do this using variables. Java does not allow you to declare variables dynamically. It is not that kind of programming language ...
If it is mandatory that the polynomials are stored in an ArrayList then:
get the user to refer to the polynomials by number (i.e. position in the list) instead of by name, or
create a hashmap that maps from names to positions in the list, or
store the polynomials in BOTH an ArrayList<String> AND a HashMap<String, String>.
Actually, I think that you may have misinterpreted the requirements for your programming exercise. I suspect that you are asked to represent each individual polynomial as an ArrayList (or a custom class that has an ArrayList inside it). Representing a polynomial as a String doesn't allow you to do any operations on it ... without first parsing the String and turning it into another form.
As you absolutely need to use ArrayList class to store your polynomials you can use its add(int index, E Element) method as follows:
List polynomials= new ArrayList();
for(int k=0;k < counter;k++){
polynomials.add(k, new Poly(...));
}
You won't have P0, P1, ... but polynomials.get(0), polynomials.get(1), ...
Thanks to gmhk in this.
So why doesn't this work? Not really sure why this isn't possible- I just want to store an array of size 2 inside a 2d array.
I know this would be equivalent to setting storage[0][0] = array[0] and storage[0][1] = array[1], but just wondering why this is incorrect.
public class Test {
public static void main(String[] args) {
boolean[][] storage = new boolean[10][2];
boolean[] array = new boolean[2];
array[0] = true;
array[1] = false;
storage[0][] = array; //Why can't I do this?
}
}
Thanks in advance
You have a stray pair of brackets in your assignment. Just use
storage[0] = array;
First of all boolean[][] storage = new boolean[10][2] declares an array and initialise it.
So, you have created 11 arrays. One of boolean[] element type and 10 of boolean type.
It's good, If you want to access it's members directly, but if you create an inner array lately with new boolean[], it's an overhead.
Use boolean[][] storage = new boolean[10][]; instead.
Then, you can access it's elements, which are boolean[] type, and assign your array to it.
storage[0] = array;
Your problem is the stray square brackets(as I'm sure you know). Your code should look like this:
storage[0] = array;
The previous answers did not really explain why though, so that's what I'll do.
What your trying to do is make the first position(storage[0]) hold the same value as array. array is 1 dimensional, so it can only be part of storage, which is 2 dimensional.
Question: Why does the following print out:
ChildB___Parent of ChildB
ChildB___Parent of ChildB
Instead of what I think it should print out:
ChildA___Parent of ChildA
ChildB___Parent of ChildB
Short Self Contained Generalized Example of Issue:
import java.util.ArrayList;
import java.util.List;
public class StackExchangeQuestion1 {
public static void main(String[] args){
List<String[]> list = new ArrayList();
String[] pair = {"childID","parentID"}; //for readability this gets overwritten
//adding values to list
pair[0] = "ChildA";
pair[1] = "Parent of ChildA";
list.add(pair);
pair[0] = "ChildB";
pair[1] = "Parent of ChildB";
list.add(pair);
//checking values in list
for(int i=0;i<list.size();i++){
pair = list.get(i); //variable reuse for readability
System.out.println(pair[0]+"___"+pair[1]);
}
}}//end class and main
You are adding the same String[] reference twice to your list. Because of this, both elements in your list point to the same object. So, when you overwrote your array, you were really writing to the same piece of memory. The list was referencing this piece of memory twice, so you get 2 identical print statements.
Java will pass all non-primitive values by reference (that means it will pass a pointer to where a non-primitive object is stored in memory.)
If you were storing integers instead like so:
int a = 10;
list.add(a);
a = 20;
list.add(a);
Everything would be fine, because a is an interger, integers are primtive values, and primitive values are passed by value. This means the data is stored in a is copied to the list, not the point in memory a is held at.
Strings and arrays of any sort, however, are non-primitive.
To fix your code then, you need to pass 2 separate references to your list:
String[] pair1 = {"ChildA","Parent of ChildA"};
String[] pare2 = {"ChildB", "Parent of ChildB"};
//adding values to list
list.add(pair1);
list.add(pair2);
Edit:
You'd expressed concerns in comments about verbosity. First, I think your code isn't verbose. But if you're truly concerned about it here's a way to shorten it:
list.add(new String[]{"ChildA","Parent of ChildA"});
list.add(new String[]{"ChildB","Parent of ChildB"});
Because an ArrayList stores references, not objects. The reference pair always refers to the same object; you're simply adding that reference to your list twice.
Your string object array is overriding here. Your last change only will reflect in your string because list will store object's reference. If you want to get your assumed output create new objects every time before you set value.
I was wondering what the simplest way would be to implement an array who's rank is specified at runtime.
The example I am working on stores a array of boolean values for lattice points, and I want the user to be able to chose how many spatial dimensions the model uses at runtime.
I've looked at the Array.newInstance() method:
dimensionOfSpace = userInputValue; // this value comes from GUI or whatever
int latticeLength = 5; // square lattice for simplicity
int[] dimensions = new int[dimensionOfSpace];
for(int i = 0; i < l.length; i++) l[i] = length;
Object lattice = Array.newInstance(boolean.class, dimensions);
But accessing these values in any sort of way seems to require horribly slow methods such as recursively using Array.get until the returned value is no longer an array, i.e. using isArray().
Am I missing an obvious solution here? I would love to be able to access the values in a way similar to foo[i][j][k].
Looks like what you are looking for is for some way to declare how many dimensions an array has at runtime. I don't know how this could be done using a multidimensional ArrayList, or any multidimensional structure where you have to specify the dimensionality at compile time.
The only answer I see is to use a simple linear array wrapped in a class that converts multidimensional coordinate to and from the its position in the underlying array. This is basically how languages such as C stores multidimensional arrays by using one contiguous chunk of memory.
The code would look something like this:
import java.util.*;
class MultiArray<T>{
private int[] dimensions;
private Object[] array;
public MultiArray(int ... dimensions){
this.dimensions=dimensions;
//Utils.product returns the product of the ints in an array
array=new Object[Utils.product(dimensions)];
}
public void set(T value, int ... coords){
int pos=computePos(coords);
array[pos]=value;
}
public T get(int ... coords){
int pos=computePos(coords);
return (T)(array[pos]);
}
private int computePos(int[] coords){
int pos=0;
int factor=1;
for (int i=0;i<coords.length;i++){
pos+=factor*coords[i];
factor*=dimensions[i];
}
return pos;
}
}
class Main{
public static void main(String args[]){
MultiArray<Integer> m=new MultiArray<Integer>(new int[]{5,4,3});
Random r=new Random();
for(int i=0;i<5;i++)
for(int j=0;j<4;j++)
for(int k=0;k<3;k++)
m.set(r.nextInt(),i,j,k);
for(int i=0;i<5;i++){
for(int j=0;j<4;j++){
for(int k=0;k<3;k++)
System.out.print(m.get(i,j,k)+" ");
System.out.println("");
}
System.out.println("\n");
}
}
}
class Utils{
public static int product(int...a){
int ret=1;
for (int x:a) ret*=x;
return ret;
}
}
Checkout Java Collections. It contains a class called ArrayList that grows in size as needed.
One dimensional
List<Boolean> a = new ArrayList<Boolean>();
Two Dimensional
List<List<Boolean>> b = new List<List<Boolean>>();
Three Dimensional
List<List<List<Boolean>>> c = new List<List<List<Boolean>>>();
And you'd access the item as c.get(i).get(j).get(k) instead of c[i][j][k] as in a 3d array. Or even better, wrap it in your own Class, and use a get() method there. So it becomes:
c.get(i, j, k);
Edit:
To have a multi-dimensional list of depth N, remove the Boolean type indictor and simply create lists as
List level1 = new ArrayList();
List level2 = new ArrayList();
List level3 = new ArrayList();
level1.add(level2);
level2.add(level3);
and so on..
I'm going to use the term 'rank' to mean the 'number-of-dimensions' in your array. So a vector has rank 1, a matrix has rank 2 and so on. You've already accepted an answer that by your own admission is not quite what you want. Here's an alternative to settling for less:
Recall that computer memory is essentially linear and that what a compiler does when it gives you arrays is actually take care of transforming an index expression into a linear address. This is simplest to think about if you assume that all arrays are in contiguous memory, not always true. Suppose that you make a declaration such as ARRAY_OF_TYPE[10][10][10], ie it has 1000 elements. Then the element at position [3][5][4] is (my arrays are indexed from 1 not 0 -- change the sums that follow if you want to) at location baseAddress+354*size_of_element_of_TYPE.
I expect you know where I'm going on this by now ...
At run time your program prompts for a list of integers from the user. Each integer specifies the size of one of the dimensions of the array, the number of integers specifies the rank of the array. Your program does some multiplications and you allocate a vector of the right length. OK, you have to write the indexing and de-indexing functions, but these should be fairly straightforward.
et voila you have an array whose rank is established at run time.
I did a quick google search for "java tensor" which came up with DJEP, could that be something which fits your bill?