0

Say we got a varargs method that takes String... args as input. It's no problem to pass a normal String[] array to that function, but unfortunately it doesn't work when the method starts with other Strings:

String[] someStringArray = new String[5];
varargsMethod("hello", "world", someStringArray);

I know it's no problem to simply prepend the static Strings to the list and pass that as a result, but the readability of my code would suffer in my specifc case, so I'd like to avoid that if possible in any way.

Is it possible?

Selbi
  • 813
  • 7
  • 23
  • 1
    In some languages (perl, python, javascript, groovy, kotlin, etc.) you could use the spread (or splat) operator to explode the array in as many parameters as the array holds elements, but it isn't implemented in Java. Here's a question on the topic : https://stackoverflow.com/questions/46388620/java-spread-operator – Aaron Apr 11 '18 at 12:12

3 Answers3

0

In this case, I suggest you to use an array as first parameter and varargs as second parameter.

For example:

varargsMethod(String[] input, String... extras)

And an overload

varargsMethod(String... extras)
Mạnh Quyết Nguyễn
  • 17,677
  • 1
  • 23
  • 51
  • I forgot to mention that I cannot change the method. It's a ProcessBuilder, just for context. – Selbi Apr 11 '18 at 12:10
  • It's easy. In the first method, you just combine the parameter `input` and `extras` to an array and call the `varargsMethod(String... extras)` function So the first function become an utility-like / helper function – Mạnh Quyết Nguyễn Apr 11 '18 at 12:12
0

You could do this:

varargsMethod(
    Stream.concat(Stream.of("hello", "world"),Stream.of(someStringArray))
    .toArray(String[]::new));

That's "prepending" which you said you were trying to avoid, but at least it's done "in-line" so the readability is not hurt as much as it would be if you did it with multiple statements.

DodgyCodeException
  • 5,963
  • 3
  • 21
  • 42
  • That works and does answer OP's question as I understand it, but I disagree with the inline presentation making the code more readable and would much rather see a plain array or List being constructed in the previous lines. – Aaron Apr 11 '18 at 12:35
  • Hmm, gotta agree with @Aaron. My primary concern isn't getting it available it one line, it's readability. – Selbi Apr 11 '18 at 12:39
0

I suggest you simply construct your command+parameters list beforehand using List.add and .addAll :

List<String> commandAndParams = new ArrayList();
commandAndParams.add("command");
commandAndParams.add("-p");
commandAndParams.addAll(pParametersList);
commandAndParams.addAll(Arrays.asList(new String[]{"-v", "-t", "-s"}));
commandAndParams.add("-o"); commandAndParams.add(outputfile);

// a varargs method would need a .toArray() cast before being called, 
// but ProcessBuilder has a List<String> constructor.
ProcessBuilder pb = new ProcessBuilder(commandAndParams);

I've mixed different styles to let you chose which helps understanding the most, but you should avoid mixing them all like that.

I prefer recreating the list to prepending the needed element to the existing one simply because I suppose your existing list has a precise meaning which is represented through its variable's name and differs from "a command and its list of parameters I'm going to feed to ProcessBuilder". You should chose a variable name more meaningful that commandAndParams if you can of course.

Aaron
  • 24,009
  • 2
  • 33
  • 57