Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unpack an array into different arguments on method call

Tags:

java

I would like to know if it is possible to unpack an Object array into separate Object on method call which accepts vargs. This question is similar to this one.

I have a code like:

public class Test {
    public static Object doWork(Object... objects){
        System.out.println(objects.length);
        return objects;
    }

    public static void main(String[] args){
        Object res = doWork("one", "two");
        res = doWork("three", res);
    }
}

I would like to unpack the res object in the second call so it would receive an object array with length 3 instead of length 2 as now (where the second position is an Object array of length 2, having then all three arguments).

Is even that possible in Java?


More detailed:

By doing

Object res = doWork("one", "two");
res = doWork("three", res);

the second call gets called as:

doWork( Object[ "three", Object[ "one", "two" ] ] )

where i would like:

doWork(Object[ "one", "two", "three" ] )

I know this can be achieved by doing:

public static void main(String[] args){
res = doWork("one", "two");
    List<Object> los = Arrays.asList(res);
    los = new ArrayList<>(los);     // Can't modify an underlying array
    los.add("three");
    res = doWork(los.toArray());
}

But I'm looking for something like the unpack Lua built in function or the Python way described in the previously mentioned SO question.


Both answers given by @chancea and @Cyrille-ka are good and also solve the problem. One of the facts that might be a good idea to take into account is if the signature of the method can be modified. @cyrille-ka answer respects the function's signature, whereas @chancea does not. However I think in most cases one can just write asimple wrapper function to another one, so that shouldn't be a problem. On the other hand @chancea's way might be easier to use while programing (there no possible mistake of forgetting to call the unpack function).

like image 587
Javier Mr Avatar asked Jul 24 '13 14:07

Javier Mr


People also ask

Can you pass an entire array as an argument to the method explain?

A whole array cannot be passed as an argument to a function in C++. You can, however, pass a pointer to an array without an index by specifying the array's name.

How do you bring an array into a method?

Passing Array To The Method In Java Arrays can be passed to other methods just like how you pass primitive data type's arguments. To pass an array as an argument to a method, you just have to pass the name of the array without square brackets. The method prototype should match to accept the argument of the array type.


2 Answers

Well, there is no syntactic sugar à la Python or Lua for that in Java, but you can create your own unpack method:

@SafeVarargs
public static <E> Object[] unpack(E... objects) {
    List<Object> list = new ArrayList<Object>();
    for (Object object : objects) {
        if (object instanceof Object[]) {
            list.addAll(Arrays.asList((Object[]) object));
        }
        else{
            list.add(object);
        }
    }

    return list.toArray(new Object[list.size()]);
}

This will returns an array containing all the input elements, unpacked.

Then you can call it in your main method:

res = doWork(unpack("three", res));

The reason I make this method generic is that you can call it with, for example, a String[] array, without generating a warning. For some reason, the Java compiler thinks that this method has a chance of "polluting the heap", but it is not the case, that's why I added a @SafeVarargs annotation.

like image 197
Cyrille Ka Avatar answered Sep 22 '22 05:09

Cyrille Ka


This does not implement the Unpack solution, instead it goes about it by making an overload method as I said in my comment. I do not know if this at all what you wanted, but I got it to work and I felt like I would post this for reference.

public class Test {
    public static Object doWork(Object... objects){
        System.out.println(objects.length);
        return objects;
    }

    // this is the method that will concatenate the arrays for you
    public static Object doWork(Object[] objects1, Object... objects2){
        System.out.println(objects1.length + "+" + objects2.length);
        Object[] retval = new Object[objects1.length+objects2.length];
        System.arraycopy(objects1, 0, retval, 0, objects1.length);
        System.arraycopy(objects2, 0, retval, objects1.length, objects2.length);
        return retval;
    }

    public static void main(String[] args){
        Object res = doWork("one", "two");
        res = doWork((Object[])res, "three");
        Object[] res2 = (Object[])res; // = {one, two, three}
    }
}
like image 33
chancea Avatar answered Sep 20 '22 05:09

chancea