Home » Java » java – Why introduce a new array in a method? Why not reuse the parameter?-Exceptionshub

java – Why introduce a new array in a method? Why not reuse the parameter?-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

In the method normalize I input an array say, {1, 2, 3, 4}, and the return is a normalized array, {0.1, 0.2, 0.3, 0.4}.
I know I should introduce a new array in the method (b in the following), but why actually?

public static double[] normalize(double[] a) {
    double[] b = new double[a.length];
    double sum = 0;
        for (int i = 0; i < b.length; i++) {
            sum += a[i];
        }
        for (int i = 0; i < b.length; i++) {
            b[i] = a[i]/sum;
        }
    return b;
}
Input: 1 2 3 4 
Output: 0.1 0.2 0.3 0.4

Why is the following wrong:

public static double[] normalize(double[] a) {
    double sum = 0;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        for (int i = 0; i < a.length; i++) {
            a[i] = a[i]/sum;
        }
    return a;
}
Input: 1 2 3 4
Output: 0.1 0.2 0.3 0.4
How to&Answers:

The difference is that one method updates the input array in place, whereas the other one keeps the array intact and returns a copy.

Neither is wrong(*), both ways have their place, you just need to make sure to the caller knows what is happening.

If you update in-place, you can make that clearer by making the method void instead of returning a (redundant) reference to the same array.


(*) In modern practice, prefer immutable data structures. So unless performance is a real issue, go with the “safer” variant.

Answer:

In the first case, the original array will stay unmodified when the method returns.

In the second case, the original array will be modified (even when it returns to where it was called), irregardless to whatever array you set the return value to afterward.

Both options can be viable, but it depends on the case and what is expected to happen. However, typically I would expect when you pass a parameter to a method, the parameter will not be modified when the method returns.

Documentation can make it clear that the original array will be modified or if it will not be.

Side Note:

This will not work the same way if you modify a directly, instead of modifying the values contained within:

public static void normalize(double[] a) {
    a = new double[5];
}

a will remain unchanged in this case when the method returns.

Answer:

In my opinion, you are creating a new variable with new values. The method receives one var and returns another var.

It’s more reader-friendly.

Answer:

Explaining the byte code behavior, and the difference of creating a new array or reusing the same input is not what you are asking for I think. Because it is really easy to see the difference.

What I think you are looking for, is a conceptual analysis of the difference. From my perspective, “functions” in any language should be treated as math functions. You give X and Y, and the function returns Z. Imagine you have a rectangle which height = a and width = b. If you want the area of it, you pass a and b and you get A . If you want the perimeter, you pass a and b and you get P.

This makes your code more readable, reusable, more cohesive, more testable.

Answer:

None of them is wrong. It’s just a matter of whether you want to keep your original array unchanged or you want to change it while normalizing. Check the output of the code given below:

import java.util.Arrays;

public class Numbers {
    public static void main(String[] args) {
        double[] a = { 1, 2, 3, 4 };
        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(normalize1(a)));// No change in the array
        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(normalize2(a)));// The array will be changed
        System.out.println(Arrays.toString(a));
    }

    public static double[] normalize1(double[] a) {
        double[] b = new double[a.length];
        double sum = 0;
        for (int i = 0; i < b.length; i++) {
            sum += a[i];
        }
        for (int i = 0; i < b.length; i++) {
            b[i] = a[i] / sum;
        }
        return b;
    }

    public static double[] normalize2(double[] a) {
        double sum = 0;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        for (int i = 0; i < a.length; i++) {
            a[i] = a[i] / sum;
        }
        return a;
    }
}

Output:

[1.0, 2.0, 3.0, 4.0]
[0.1, 0.2, 0.3, 0.4]
[1.0, 2.0, 3.0, 4.0]
[0.1, 0.2, 0.3, 0.4]
[0.1, 0.2, 0.3, 0.4]

I recommend you check this to learn more about it.