Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass elements of an arrayList to variadic function

I've got an arrayList filled with elements. I would like to pass the elements of that array list as arguments to a variadic function.

My function

public SequenceEntityModifier(final IEntityModifier... pEntityModifiers)

My ArrayList

ArrayList<IEntityModifier> arr = new ArrayList<IEntityModifier>();
arr.add(new MoveXModifier(1, 50, 120));
arr.add(new MoveXModifier(1, 120, 50));

I'd like to pass it to the function as if I would pass them individually.

new SequenceEntityModifier( /* elements of arr here */ );

Is something like this possible?

Thanks in advance.

like image 369
pad Avatar asked Sep 21 '12 16:09

pad


People also ask

Can I pass ArrayList to Varargs Java?

Passing an ArrayList to method expecting vararg as parameter To do this we need to convert our ArrayList to an Array and then pass it to method expecting vararg. We can do this in single line i.e. * elements passed. // function accepting varargs.

How do you pass a list to a variable argument in Java?

Use List. toArray(T[] arr) : yourVarargMethod(yourList.

How do you write a variadic function?

The variadic function consists of at least one fixed variable and then an ellipsis(…) as the last parameter. This enables access to variadic function arguments. *argN* is the last fixed argument in the variadic function. This one accesses the next variadic function argument.


3 Answers

Just do:

new SequenceEntityModifier(arr.toArray(new IEntityModifier[arr.size()]));

This copies the ArrayList to the given array and returns it. All vararg functions can also take arrays for the argument, so for:

public void doSomething(Object... objs)

All the legal calls are:

doSomething(); // Empty array
doSomething(obj1); // One element
doSomething(obj1, obj2); // Two elements
doSomething(new Object[] { obj1, obj2 }); // Two elements, but passed as array

One caveat:

Vararg calls involving primitive arrays don't work as you would expect. For example:

public static void doSomething(Object... objs) {
    for (Object obj : objs) {
        System.out.println(obj);
    }
}

public static void main(String[] args) {
    int[] intArray = {1, 2, 3};
    doSomething(intArray);
}

One might expect this to print 1, 2, and 3, on separate lines. Instead, it prints something like [I@1242719c (the default toString result for an int[]). This is because it's ultimately creating an Object[] with one element, which is our int[], e.g.:

// Basically what the code above was doing
Object[] objs = new Object[] { intArray };

Same goes for double[], char[], and other primitive array types. Note that this can be fixed simply by changing the type of intArray to Integer[]. This may not be simple if you're working with an existing array since you cannot cast an int[] directly to an Integer[] (see this question, I'm particularly fond of the ArrayUtils.toObject methods from Apache Commons Lang).

like image 63
Brian Avatar answered Oct 28 '22 01:10

Brian


The construct IEntityModifier... is syntactic sugar for IEntityModifier[]

See the appropriate JLS section (8.4.1 Formal Parameters)

like image 24
Brian Agnew Avatar answered Oct 28 '22 01:10

Brian Agnew


I always create an overload that takes Iterable< ? extends IEntityModifier >, and make the variadic version forward to this one using Arrays.asList(), which is cheap.

like image 24
Judge Mental Avatar answered Oct 28 '22 02:10

Judge Mental