3

I want to pass an array and a single object to method which has varargs.

However, the most obvious solution doesn't seem to work:

public static final String[] ARRAY_ARGS =  {"first argument", "second argument"};
public static String additionalArgument = "additional argument";

public static void foo(String... args) {
    // ...
}

public static void main(String[] args) {
    foo(ARRAY_ARGS,additionalArgument); // error! won't compile
}

How can I fix this?

0

6 Answers 6

3

A variable argument is equivalent to an array. Hence, the compiler does not accept an array and a string. One solution is to create an array from the original with the additional string added to it:

List<String> originalList = Arrays.asList(ARRAY_ARGS);
List<String> list = new ArrayList<String>(originalList);
Collections.copy(list, originalList);
list.add(additionalArgument);
foo(list.toArray(new String[list.size()]));

The Collections.copy is needed because adding to the list returned by Arrays.asList throws a java.lang.UnsupportedOperationException as the latter returns a list that extends AbstractList which does not support adding elements.

Another solution is to create a new array and individually add the elements:

String[] arr = new String[3];
arr[0] = ARRAY_ARGS[0];
arr[1] = ARRAY_ARGS[1];
arr[2] = additionalArgument;
foo(arr);

Or you can simply call foo with the individual parameters:

foo(ARRAY_ARGS[0], ARRAY_ARGS[1], additionalArgument);
Sign up to request clarification or add additional context in comments.

2 Comments

@Kao In this case you can expect it to be 3, but setting it to zero won't harm because it will automatically create an array that fits the elements.
A more generic way to get the right array with the respective length would be list.toArray(new String[list.size()])
1

The argument String ... args is shorthand for String[]. Therefore you get an error when you are calling foo(args,additionalargument) since the method declaration of foo is foo(String[] str) instead of foo(String[],String).

Comments

1

You can do this, if the first argument to your method is the single string, followed by the varargs:

public static void foo(String a, String... args) {
    System.out.println("a = " + a);
    System.out.println("args = " + Arrays.toString(args));
}

Then calling foo("a", "b", "c") prints

a = a
args = [b, c]

Comments

0

If you must distinguish between the array and the single string, concatenate the array values in a format you can "recognize", pass the "array-string" and the single string as parameters to the main method, and then parse the "array-string" in the relevant (foo) method.

Comments

0

A Java 8 approach to solve this problem is the following oneliner:

foo(Stream.concat(Arrays.stream(ARRAY_ARGS), Stream.of(additionalArgument)).toArray(String[]::new)); 

This creates a new String[] that can be passed to foo. Furthermore, foo must be made static, otherwise the code will not compile.

The only parameters that you can pass to the foo-method is either a String array or a bunch of individual Strings.

Comments

0

Simple yet elegant solution using Apache Commons Lang library:

foo(ArrayUtils.addAll(ARRAY_ARGS,additionalArgument)); 

3 Comments

This won't work because it returns an Object[] not a String[]. No generic method works nicely either because you cannot create a new T[]. Unless you find a method specific to String, the nicest possible call would look something like foo(LibraryClass.add(ARRAY_ARGS, additionalArgument, new String[1 + ARRAY_ARGS.length]));
@pbabcdefp It will work. There is an overloaded version of ArrayUtils.addAll() which returns String[]. See docs.
Apologies. You are right, it will work. But it returns a T[] not a String[]. They must use reflection to create the new T[].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.