Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to concate two int arrays without using a return type?

Tags:

java

arrays

This particular problem I'm working on is listed as such:

ConcatArrays(int[] listA, int[] listB, int[] listC) with no return type. 1. The method passes the formal array parameters listA and listB, then return the concatenated array listC. 2. The first part of listC contains elements which are the same as the corresponding elements of listA and the second part contains the same elements as listB. The length of listC is listA.length + listB.length.

This is what I have and obviously it's not going to work. Is it even possible to do this without a return type/removing list c as the third parameter?

  public static void  ConcatArray(int[] listA, int[] listB, int[] listC) 
    {
         int aLen = listA.length ; 
         int bLen = listB.length;
         int cLen = listC[aLen + bLen];
    }

Edit : I appreciate all of the answers everybody, I up voted them all. This was a homework assignment and after rereading it I believe the no return type was an error because of what he said in question 1. Basically saying to return list c by using parameters listB and ListA. There were several other typos before that he has since corrected. He also gave us array1 and array 2 for our test class with values, but no array 3.

like image 402
Marcus Avatar asked Oct 25 '14 23:10

Marcus


2 Answers

Once a Java array is created, you cannot change its size. Your code does not work because an array reference is passed by value, and Java does not have passing by reference.

Returning the array is the idiomatic way of solving this in Java:

public static int[]  ConcatArray(int[] listA, int[] listB) {
    int[] res = new int[listA.length + listB.length];
    ...
    return res;
}

You can fake passing by reference through a mutable type that has a field of the desired type, like this:

class IntArrayRef {
    int[] array;
}

Now you can write your void method like this:

public static void  ConcatArray(int[] listA, int[] listB, IntArrayRef res) {
    res.array = new int[listA.length + listB.length];
    ...
}

However, if you go through the trouble of doing this, you might as well return the array.

like image 189
Sergey Kalinichenko Avatar answered Oct 17 '22 15:10

Sergey Kalinichenko


The trick is knowing that an array's contents are not what is passed to the method. An array's contents may be read and written but writing to one changes the original. Java doesn't make a fresh copy for you unless you new one up yourself. This means you can pass information back by simply doodling in what was passed to you. That's fine as long as you document the behavior so someone using the method isn't surprised when their data goes bye bye.

public static void main(String[] args)
{
    int[] a = {0, 1};
    int[] b = {2, 3};
    int[] c = new int[a.length + b.length];

    concatArray(a, b, c);

    for (int i : c)
    {
        System.out.println(i);
    }
}

/** Concatenates prefix and suffix into result which must be as large as both */
public static void concatArray(int[] prefix, int[] suffix, int[] result) 
{
     int prefixLength = prefix.length; 
     int suffixLength = suffix.length;

     if( result.length < prefixLength + suffixLength)
     {
         throw new IllegalArgumentException();
     }

     for (int i = 0; i< prefixLength; i++)
     {
         result[i] = prefix[i];
     }

     for (int i = 0; i< prefixLength; i++)
     {
         result[i+prefixLength] = suffix[i];
     }
}

output:

0
1
2
3

This same trick works with objects so long as they are not immutable. If someone hands you a bean you are free to play with it's setters and, if you weren't supposed to do that, cause all sorts of havoc.

This is why setting the identifier of an array or object to be final doesn't guarantee immutability. Anyone can still call setting methods (if they exist on the object) or make new assignments into the array. All final does is handcuff the object or array to the identifier. It does not lock the 'briefcase'. Getting rid of the setters locks the briefcase.

That's what we call immutable. Strings are immutable and that's why this trick won't work with Strings.

When you pass to a method it's like you made the identifier final. You can't change the array or object without the calling context losing track of what you're playing with. If you stick with the same array or object you can fiddle with it as much as allowed and the calling context will see whatever you've done.

Infact, whenever you return anything besides a primitive what you're really returning is a new location and saying: "Check out what I made here". This trick works simply by sticking with previously known locations.

like image 38
candied_orange Avatar answered Oct 17 '22 15:10

candied_orange