Java generic varargs method parameters

arrays, java, variadic-functions

Solution

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));
}

Problem

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? EDIT 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"); ```

Original source

Related problems