Java two varargs in one method
Solution 1
Only one vararg, sorry. But using asList() makes it almost as convenient:
public void myMethod(List<Integer> args1, List<Integer> args2) {
...
}
-----------
import static java.util.Arrays.asList;
myMethod(asList(1,2,3), asList(4,5,6));
Solution 2
In Java, only one varargs
argument is allowed and it must be the last parameter of the signature.
But all it does it convert it to an array anyway, so you should just make your two parameters explicit arrays:
public void doSomething(String[] s, int[] i){
Solution 3
A possible API design in which the calling code looks like
doSomething("a", "b").with(1,2);
through "fluent" API
public Intermediary doSomething(String... strings)
{
return new Intermediary(strings);
}
class Intermediary
{
...
public void with(int... ints)
{
reallyDoSomething(strings, ints);
}
}
void reallyDoSomething(String[] strings, int[] ints)
{
...
}
The danger is if the programmer forgot to call with(...)
doSomething("a", "b"); // nothing is done
Maybe this is a little better
with("a", "b").and(1, 2).doSomething();
Solution 4
Only one vararg
is allowed. This is because multiple vararg
arguments are ambiguous. For example, what if you passed in two varargs of the same class?
public void doSomething(String...args1, String...args2);
Where does args1 end and args2 begin? Or how about something more confusing here.
class SuperClass{}
class ChildClass extends SuperClass{}
public void doSomething(SuperClass...args1, ChildClass...args2);
ChildClass extends SuperClass, and so is can legally exist in args1, or args2. This confusion is why only one varargs
is allowed.
varargs
must also appear at the end of a method declaration.
Just declare the specific type instead as 2 arrays.
Solution 5
Although this kind of thing is occasionally useful, usually if you find that you are hitting a restriction in Java you could probably redesign something and come out much better. Here are some possible other ways to look at it...
If the two lists are related at all you probably want to create a wrapper class for the two different lists and pass in the wrapper. Wrappers around collections are almost always a good idea--they give you a place to add code that relates to the collection.
If this is a way to initialize data, parse it from a string. For instance, "abc, 123:def, 456:jhi,789" is almost embarassingly easy to split up with 2 split statements and a loop (2-3 lines of code). You can even make a little custom parser class that parses a string like that into a structure you feed into your method.
Hmm--honestly asside from initializing data I don't even know why you'd want to do this anyway, any other case and I expect you'd be passing in 2 collections and wouldn't be interested in varags at all.
T_01
Updated on January 19, 2020Comments
-
T_01 over 4 years
Is there any way in java, to create a method, which is expecting two different varargs? I know, with the same object kind it isn't possible because the compiler does'nt know where to start or to end. But why it also is'nt possible with to different Object types?
For example:
public void doSomething(String... s, int... i){ //... //... }
Is there any way to create method like this? Thank you!
-
William Morrison almost 11 yearsI dislike this as any processing on args1 or args2 would require casting. Messy.
-
rec almost 11 yearsIf you know the generic type, use it - then there is no casting. The example above would be "equivalent" to method(Object…): myMethod(List<Integer> args1, List<Integer> args2) would work without casting in the example above.
-
DaoWen almost 11 years@WilliamMorrison - It doesn't require casting if you use an actual reference type (e.g.
Integer
) instead of<?>
. -
William Morrison almost 11 years@DaoWen Maybe it should be written like that then? Or am I missing something here? Its not a genericized method...
-
T_01 almost 11 yearsokay thank you! But i understood 2 varargs of the same type doesnt make sense ^^
-
William Morrison almost 11 years@T_01 I've got an example of why its not possible with 2 different argument types. The compiler just isn't smart enough to handle that, even if the classes don't share types.
-
T_01 almost 11 yearsThank you! Yes thats right, but two fixed arrays arent good in my case.
-
rgettman almost 11 yearsThe method signature does not fix the size of the array; callers can pass in any size arrays they want.
-
rec almost 11 yearsThe convenient way to call this one is: doSomething(new String[] {"a", "b"}, new int[] {1,2}). Doable. The benefit here is that in the int case, no the int stays int and is not auto-boxed to Integer as in the variant using asList(). Still, personally I prefer the asList() variant which is less to write.
-
WVrock over 9 yearsI had to also import
java.util.List;
to make it work. What is weird is eclipse does not auto importjava.util.Arrays.asList;
. Just in case this helps anyone, I want to point out thatargs1.get(1)
is the way to get the members of the List. -
T_01 over 6 yearsi wonder why someone woud answer on an > 4 year old question, which already has an accepted answer.. ^^ but thank you anyway
-
Mark Rotteveel over 6 years@T_01 I was writing this as an answer to another question when it was closed as a duplicate of this question, so I decided to not let that go to waste and post it here instead.