I am wondering if there is an easy, elegant and reusable way to pass a string and a string array to a method that expect varargs.
/**
* The entry point with a clearly separated list of parameters.
*/
public void separated(String p1, String ... p2) {
merged(p1, p2, "another string", new String[]{"and", "those", "one"});
}
/**
* For instance, this method outputs all the parameters.
*/
public void merged(String ... p) {
// magic trick
}
Even if all the types are consistent (String
) I cannot find a way to tell to the JVM to flatten p2 and inject it to the merged parameter list?
At this point the only way is to create a new array, copy everything into it and pass it to the function.
Any idea?
Base on your proposal here is the generic method I'll use:
/**
* Merge the T and T[] parameters into a new array.
*
* @param type the destination array type
* @param parameters the parameters to merge
* @param <T> Any type
* @return the new holder
*/
@SuppressWarnings("unchecked")
public static <T> T[] normalize(Class<T> type, Object... parameters) {
List<T> flatten = new ArrayList<>();
for (Object p : parameters) {
if (p == null) {
// hum... assume it is a single element
flatten.add(null);
continue;
}
if (type.isInstance(p)) {
flatten.add((T) p);
continue;
}
if (p.getClass().isArray() &&
p.getClass().getComponentType().equals(type)) {
Collections.addAll(flatten, (T[]) p);
} else {
throw new RuntimeException("should be " + type.getName() +
" or " + type.getName() +
"[] but was " + p.getClass());
}
}
return flatten.toArray((T[]) Array.newInstance(type, flatten.size()));
}
normalize(String.class, "1", "2", new String[]{"3", "4", null}, null, "7", "8");
Variable Arguments (Varargs) in Java is a method that takes a variable number of arguments. Variable Arguments in Java simplifies the creation of methods that need to take a variable number of arguments.
Each method can only have one varargs parameter. The varargs argument must be the last parameter.
Rules to follow while using varargs in JavaWe can have only one variable argument per method. If you try to use more than one variable arguments a compile time error is generated.
In Java, an argument of a method can accept arbitrary number of values. This argument that can accept variable number of values is called varargs. In order to define vararg, ... (three dots) is used in the formal parameter of a method.
I don't think there is a way to have the scalar and the array implicitly flattened into a single array.
The cleanest solution I can think of is to use a helper function:
// generic helper function
public static<T> T[] join(T scalar, T[] arr) {
T[] ret = Arrays.copyOfRange(arr, 0, arr.length + 1);
System.arraycopy(ret, 0, ret, 1, arr.length);
ret[0] = scalar;
return ret;
}
public void separated(String p1, String ... p2) {
merged(join(p1, p2));
}
Changing the signature of merge
to:
public<T> void merged(T ... p)
Will at least allow you to call merge without problems. You would have to deal with arrays of string as a parameter, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With