Java two varargs in one method

后端 未结 12 2071
小鲜肉
小鲜肉 2020-11-27 21:08

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 kn

相关标签:
12条回答
  • 2020-11-27 21:51

    I just read another question about this "pattern", but it is already removed, so I would like to propose a different approach to this problem, as I didn't see here this solution.

    Instead to force the developer to wrapping the inputs parameter on List or Array, it will be useful to use a "curry" approach, or better the builder pattern.

    Consider the following code:

    /**
     * Just a trivial implementation
     */
    public class JavaWithCurry {
    
        private List<Integer> numbers = new ArrayList<Integer>();
        private List<String> strings = new ArrayList<String>();
    
        public JavaWithCurry doSomething(int n) {
    
            numbers.add(n);
    
            return this;
        }
    
        public JavaWithCurry doSomething(String s) {
    
            strings.add(s);
    
            return this;
    
        }
    
        public void result() {
    
            int sum = -1;
    
            for (int n : numbers) {
                sum += n;
            }
    
    
            StringBuilder out = new StringBuilder();
    
            for (String s : strings) {
    
                out.append(s).append(" ");
    
            }
    
            System.out.println(out.toString() + sum);
    
        }
    
        public static void main(String[] args) {
    
            JavaWithCurry jwc = new JavaWithCurry();
    
            jwc.doSomething(1)
                    .doSomething(2)
                    .doSomething(3)
                    .doSomething(4)
                    .doSomething(5)
                    .doSomething("a")
                    .doSomething("b")
                    .doSomething("c")
                    .result();
    
        }
    
    }
    

    As you can see you in this way, you could add new elements of which type you need when you need.

    All the implementation is wrapped.

    0 讨论(0)
  • 2020-11-27 21:52

    If you are not going to be passing a large number of Strings most of the time for the first argument you could provide a bunch of overloads that take different numbers of Strings and wrap them in an array before calling a method that takes the array as the first argument.

    public void doSomething(int... i){
        doSomething(new String[0], i);
    }
    public void doSomething(String s, int... i){
        doSomething(new String[]{ s }, i);
    }
    public void doSomething(String s1, String s2, int... i){
        doSomething(new String[]{ s1, s2 }, i);
    }
    public void doSomething(String s1, String s2, String s3, int... i){
        doSomething(new String[]{ s1, s2, s3 }, i);
    }
    public void doSomething(String[] s, int... i) {
        // ...
        // ...
    }
    
    0 讨论(0)
  • 2020-11-27 21:54

    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.

    0 讨论(0)
  • 2020-11-27 21:57

    It is not possible because the Java Language Specification says so (see 8.4.1. Formal Parameters):

    The last formal parameter of a method or constructor is special: it may be a variable arity parameter, indicated by an ellipsis following the type.

    Note that the ellipsis (...) is a token unto itself (§3.11). It is possible to put whitespace between it and the type, but this is discouraged as a matter of style.

    If the last formal parameter is a variable arity parameter, the method is a variable arity method. Otherwise, it is a fixed arity method.

    As to why only one and only the last parameter, that would be a guess, but probably because allowing that could lead to undecidable or ambiguous problems (eg consider what happens with method(String... strings, Object... objects)), and only allowing non-intersecting types would lead to complications (eg considering refactorings where previously non-intersecting types suddenly are), lack of clarity when it does or does not work, and complexity for the compiler to decide when it is applicable or not.

    0 讨论(0)
  • 2020-11-27 21:58

    follwing on Lemuel Adane (cant comment on the post, due to lack of rep :))

    if you use

    public void f(Object... args){}
    

    then you may loop using How to determine an object's class (in Java)?

    like for instance

    {
       int i = 0;
       while(i< args.length && args[i] instanceof String){
             System.out.println((String) args[i]);
             i++ ;
       }
       int sum = 0;
       while(i< args.length){
             sum += (int) args[i];
             i++ ;
       }
       System.out.println(sum);
    }
    

    or anything you intend to do.

    0 讨论(0)
  • 2020-11-27 22:02

    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));
    
    0 讨论(0)
提交回复
热议问题