Method is changing values of my array unexpectedly - java

Method calculating percentages (from array which I don't want to be changed but it is):
private float values[] = { AGREE, DISAGREE };
private float[] calculateData(float[] data) {
// TODO Auto-generated method stub
float total = 0;
for (int i = 0; i < data.length; i++) {
total += data[i];
}
// 180 is the amount of degrees of the circle - setting it up to half
// circle 360 means full circle
for (int i = 0; i < data.length; i++) {
data[i] = 180 * (data[i] / total);
}
Calling the method:
float[] degrees = calculateData(values);
If I log the values of array before this method was called I get 1.0,1.0 but after method was called I get 90.0,90.0 why? If I don't change values[].
I know that it is happening here in that method because when I remove it I get 1.0,1.0 (what I actually want to get)
EDIT:
Thank you for the answers so if I understand it correctly: if parameter of the method is changed also the object set to be parameter, when method was called, becomes changed.

You are modifying your array here: data[i] = 180 * (data[i] / total);
You get the address of the array in the parameter of your function, not a copy of it, so if you modify it in your function, it will modify the array you passed when walling your calculateData function.

You are modifying the array in the second for

Array variables are just references. If you pass values as data, data points to the same array as values. Consider the following example:
int[] a = new int[] {1, 2, 3};
int[] b = a;
b[0] = 4;
// a is now {4, 2, 3}
If you don't want this, you need to make a copy:
Make copy of array Java

You need a new array inside your method like newData in the code below, which you need to return from a method:
private float[] calculateData(float[] data) {
float[] newData;
float total = 0;
for (int i = 0; i < data.length; i++) {
total += data[i];
}
for (int i = 0; i < data.length; i++) {
newData[i] = 180 * (data[i] / total);
}
return newData;
}

Related

Write a function called arraySum that returns the sum (as an int) of all the values in a two-dimensional array of int values (Java)

I am trying to sum all the int values of a 2D array. I named it array. my function is then called arraySum. If arraySum is null, I return 0. Otherwise, it goes through two for-loops, summing the values of these arrays.
int i = 0;
int j = 0;
static int sum = 0;
int[][] array = new int[i][j];
static int arraySum(int[][] array) {
if (array == null) { // test if the incoming param is null
return 0;
} else {
for (int i = 0; i < array.length; i++) { // length of the outer array
for (int j = 0; j < array[i].length; j++) { // length of the inner array
sum += array[i][j];
}
}
return sum; // moved out of the loop
}
}
my error message:
java.lang.AssertionError: Incorrect result: expected [-217085] but found [-308126]
Fixing the method signature is the first step.
Then you'll need to fix the null check.
Then your loops need to check the size of the inner and outer arrays.
Move the return statement.
Here's the fixed code:
static int arraySum(int[][] array) { // fix the signature
if (array == null) { // test if the incoming param is null
return 0;
} else {
int sum = 0; // you need this in the scope of the method - it will be returned at the end
for (int i = 0; i < array.length; i++) { // length of the outer array
for (int j = 0; j < array[i].length; j++) { // length of the inner array
sum += array[i][j];
}
}
return sum; // moved out of the loop
}
}
Edit: I've concentrated on just the method now - how you call it is up to you. Please note that the method will not affect any externally defined sum variable. It will return the sum and it's up to the caller to store that value somewhere.
Avoid using primitive for statement. See following:
static int arraySum(int[][] array) {
int sum = 0;
if (array == null) return 0;
for(int[] row: array){
for(int col : row) {
sum += col;
}
}
return sum;
}
Streams can do this too:
//Create 2D array
int[][] array = {{1,2,3},{4,5},{6}};
//Sum all elements of array
int sum = Stream.of(array).flatMapToInt(IntStream::of).sum();
System.out.println(sum);
Picking apart the summing code:
Stream.of(array)
Turns the 2D array of type int[][] into a Stream<int[]>. From here, we need to go one level deeper to process each child array in the 2D array as the stream only streams the first dimension.
So at this point we'll have a stream that contains:
an int[] array containing {1,2,3}
an int[] array containing {4,5}
an int[] array containing {6}
.flatMapToInt(IntStream::of)
So far we have a Stream of int[], still two-dimensional. Flat map flattens the structure into a single stream of ints.
flatMapToInt() expands each int[] element of the stream into one or more int values. IntStream.of() takes an array int[] and turns it into an int stream. Combining these two gives a single stream of int values.
After the flattening, we'll have an int stream of:
{1,2,3,4,5,6}
.sum()
Now we have an IntStream with all elements expanded out from the original 2D array, this simply gets the sum of all the values.
Now the disclaimer - if you are new to Java and learning about arrays, this might be a little too advanced. I'd recommend learning about nesting for-loops and iterating over arrays. But it's also useful to know when an API can do a lot of the work for you.

How to create a temporary list from a 2d array to calculate a median?

I need to create a class ArrayMethods. With a
• public static double median(double[][] a)
method. I know that i need to create a list with all the values from the 2d arrays. Then sort it out and find the median. BUt I dont know how to create a list. Can anyone help me with this.
For the median, I have done this but it doesn't work on negative numbers or odd number of arrays:-
public static void main(String[] args) {
double[][] a = {
{1,2,3},
{4,5,6},
};
System.out.println(median(a));
}
public static double median(double[][] a2) {
double[] list = new double[a2.length*a2[0].length];
double listPos = 0;
for(double i = 0 ; i < a2.length; i++) {
for(double j = 0; j < a2[(int) i].length; j++) {
list[(int) listPos++] = a2[(int) i][(int) j];
Arrays.sort(a2[(int) i]);
}
}
double middle = list.length/2;
if ((list.length%2) == 1) {
return list[(int) middle];
}
return (list[(int) (middle-1)] + list[(int) middle]) / 2.0;
}
}
If we're talking about simply creating a list, then we will need a dynamic list able to store whatever number of values, since we only know the size of the array if we either hard-code it (never!) or at runtime. The best solution for this is a basic ArrayList.
First, we store all the values into the ArrayList, and once all values are stored, we can then sort it. As you know, it's all down hill from there. The median (using your implementation of the median) can be found now using:
public static double median(double[][] a2) {
// check for an empty array
if(a2.length == 0)
throw new IllegalStateException("The array is empty");
ArrayList<Double> list = new ArrayList<Double>();
// first, add all the elements into the linear list
for(int i = 0; i < a2.length; i++) {
for(int j = 0; j < a2[0].length; j++) {
list.add(a2[i][j]);
}
}
// second, sort them
Collections.sort(list);
// and finally, determine the median based on the number of items
int length = list.size();
// if there is an even number of values, take the average of the 2 middle values
if(length % 2 == 0)
return (list.get(length/2 - 1) + list.get(length/2)) / 2.0;
// else, return the middle value
return list.get(length / 2);
}
I also threw in the check for an empty array, but if you want to get rid of it you can. Hope this helps!

Java changing values in a 2D array

I'm working with a 2D array and what I'm trying to do in the below method is swap two values. The 'currentBoard' variable is a 2D array that needs should not be edited. The 'cpy' variable a duplicate of the 'currentBoard' and needs its variables to be changed. 'nbt' and 'bt' are 1D arrays that used to point to an index in the 2D array. The code for the function 'copyBoard' is always below if it helps
The issue I'm having is that at on the line marked with ** when the value in the 'cpy' array is changed for some reason the value in 'currentBoard' is being changed as well. I really can't figure out why this is happening....
private void Swap(int[] nbt, int[] bt, ArrayList<State> children, String direction) {
int[][] cpy = copyBoard(currentBoard);
int temp = cpy[nbt[0]][nbt[1]];
**cpy[nbt[0]][nbt[1]] = currentBoard[bt[0]][bt[1]];
cpy[bt[0]][bt[1]] = temp;
children.add(new Board(cpy, this.getGOAL(), this.getRows(), this.getColumns(), (this.getDirections() + direction + ", ")));
}
In case it helps here is the values that are assigned to the variables at the point when the code is on the line marked with **
nbt = {1, 0}
bt = {0, 0}
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
returnArray[i] = state[i];
}
return returnArray;
}
A 2D array is an array of references to arrays. So if you assign returnArray[i] = state[i], you are simply making returnArray[i] refer to the same array that state[i] refers to. Thus, modifying returnArray[i][j] will modify the j'th element of whatever state[i] was. You have to create a deep copy of the "rows", too, e.g.:
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
// deep copy of row:
returnArray[i] = Arrays.copyOf(state[i], state[i].length);
}
return returnArray;
}
Check out this short write-up on 2D arrays, it should give you a better idea of what's going on here. In particular, this little image, which represents int nums[][] = new int[5][4] (although it makes more sense in context):
By the way, your loop logic looks a little odd to me; even if the math happens to work out in your situation, it is a bit clearer to do this instead:
for (int i = 0; i < rows; i++)
Or more generally:
for (int i = 0; i < returnArray.length; i++)
These, of course, assume that state.length == rows; but you get the idea.

multiply a 2d array by a 1d array

I've initialized a 1d and 2d array and now I basically just want to be able to perform matrix multiplication on them. However, I'm not quite getting the proper answer. I think I've mixed up the for loop where I try to ensure I only multiply the correct values, but can't quite get the hang of it.
edit: I've fixed it, I was misunderstanding what the length method of a 2D array returned (thought it returned columns and not rows). The below code is my corrected code. Thanks everyone.
public static double[] getOutputArray(double[] array1D, double[][] array2D) {
int oneDLength = array1D.length;
int twoDLength = array2D[0].length;
double[] newArray = new double[array2D[0].length]; // create the array that will contain the result of the array multiplication
for (int i = 0; i < twoDLength; i++) { // use nested loops to multiply the two arrays together
double c = 0;
for (int j = 0; j < oneDLength; j++) {
double l = array1D[j];
double m = array2D[j][i];
c += l * m; // sum the products of each set of elements
}
newArray[i] = c;
}
return newArray; // pass newArray to the main method
} // end of getOutputArray method
There are some problems, first of all, you should decide how the vectors represented, are you multiplying from left or right.
For the maths: vector 1xn times matrix nxm will result in 1xm, while matrix mxn times nx1 result in mx1.
I think the following would work for you:
public static double[] getOutputArray(double[] array1D, double[][] array2D) {
int oneDLength = array1D.length;
int twoDLength = array2D.length;
double[] newArray = new double[twoDLength]; // create the array that will contain the result of the array multiplication
assert twoDLength >0 && array2D[0].length == oneDLength;
for (int i = 0; i < twoDLength; i++) { // use nested loops to multiply the two arrays together
double c = 0;
for (int j = 0; j < oneDLength; j++) {
double l = array1D[j];
double m = array2D[i][j];
c += l * m; // sum the products of each set of elements
}
newArray[i] = c;
}
return newArray; // pass newArray to the main method
} // end of getOutputArray method
I hope I did not make a mistake, while trying to fix.

Why does this not return the proper array (java)?

I have this method that doubles my initial array and then returns it as the new array. When I then reprint the new array, it doesn't show that it doubled. I will paste just the single method, but if it's not enough, let me know. It will print it correctly in the method when I use the second for loop, but when I call the method to print the array, it prints the initial array.
public static int [] doubleArray(int [] p)
{
int [] newArr = new int [p.length * 2];
for (int i = 0; i < p.length; i++)
{
newArr[i] = p[i];
}
p = newArr; //Here I set the new doubled array to equal the array in parameters
for (int i = 0; i < p.length; i++)
{
System.out.print(p[i] + " ");
}
return p;
}
you're populating newArr only through length of p
When you set p = newArr, the array p is still going to keep its size, so its length will not double. You could try to return newArr instead of p, which should give you the doubled array you're looking for.
You are only iterating to p.length. You need to modify your logic to double the length in your first for loop while retaining the correct index to use.
It does doubles the length. Did you want the values to be copied too?
public static int [] doubleArray(int [] p)
{
int [] newArr = new int [p.length * 2];
for (int i = 0; i < p.length; i++)
{
newArr[i] = p[i];
newArr[2*i] = p[i]; //copy the value
}
p = newArr; //Here I set the new doubled array to equal the array in parameters
for (int i = 0; i < p.length; i++)
{
System.out.print(p[i] + " ");
}
return p;
}
length extended.
try this...
public static void main(String[] args) {
int[] a = {1,2,4};
int[] s = doubleArray(a);
System.out.println(Arrays.toString(s));
}
it gives output [1, 2, 4, 0, 0, 0]
Arrays are objects and passed by reference. So if you expect that variable you passed to this method will change it's reference you are wrong.
I ran this code and its produces array of double length and at the beginning there are values of original array. As you use array of primitive type, empty places are populated with default values(0 for int)
Works fine for me. Are you sure you have the right reference for the returned value?
In any case have a look at System.arraycopy
public static void main (final String args[])
{
int [] p = {1,2,3,4,5,6,7,8,9};
final int [] newArr = new int [p.length * 2];
for (int i = 0; i < p.length; i++)
{
newArr[i] = p[i];
}
p = newArr; //Here I set the new doubled array to equal the array in parameters
for (int i = 0; i < p.length; i++)
{
System.out.print(p[i] + " ");
}
}
Ok, #ZouZou solved the issue. When I called the method, I needed to set the initial array to equal the method. Thus when I returned the p array, it wrote it to the initial array.
ie;
initialArray = doubleArray(initialArray);
This works totally fine for me. I guess you have called the method in main like following:
public static void main (final String args[])
{
int [] p = {1,2,3,4,5,6,7,8,9};
doubleArray(p);
for (int i = 0; i < p.length; i++)
{
System.out.print(p[i] + " ");
}
}
In the doubleArray method, you didn't extend the original array. But instead, you return a new one with extended size. So the changes will not reflect to the original array outside of the method.
To get the new one, you should catch the returned array and do printing with the new one.
Is this your actual question? Please clarify!
If yes: normally you can change the original array and make the changes reflects outside the method by changing the return type to void. Those changes could be changing elements' value. But you can't change an array's size once it is declared.

Categories

Resources