Java two varargs in one method

22,688

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.

Share:
22,688
T_01
Author by

T_01

Updated on January 19, 2020

Comments

  • T_01
    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
    William Morrison almost 11 years
    I dislike this as any processing on args1 or args2 would require casting. Messy.
  • rec
    rec almost 11 years
    If 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
    DaoWen almost 11 years
    @WilliamMorrison - It doesn't require casting if you use an actual reference type (e.g. Integer) instead of <?>.
  • William Morrison
    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
    T_01 almost 11 years
    okay thank you! But i understood 2 varargs of the same type doesnt make sense ^^
  • William Morrison
    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
    T_01 almost 11 years
    Thank you! Yes thats right, but two fixed arrays arent good in my case.
  • rgettman
    rgettman almost 11 years
    The method signature does not fix the size of the array; callers can pass in any size arrays they want.
  • rec
    rec almost 11 years
    The 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
    WVrock over 9 years
    I had to also import java.util.List; to make it work. What is weird is eclipse does not auto import java.util.Arrays.asList;. Just in case this helps anyone, I want to point out that args1.get(1) is the way to get the members of the List.
  • T_01
    T_01 over 6 years
    i wonder why someone woud answer on an > 4 year old question, which already has an accepted answer.. ^^ but thank you anyway
  • Mark Rotteveel
    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.