-3

Possible Duplicate:
java: how can i create a function that supports any number of parameters?

Is there a way to call a generic function from other functions irrespective of the input parameters ? If my input data types are all same (either int only or String only)

public class sumOfNo {

public static void main(String[] arg) {

    /**
     * Normal way of calling function to calculate sum.
     */
     int result = sum(1, 2);
     int result1 = sum(1, 2, 3);

}

/**
 * A normal function overloading method of calculating sum
 * @return
 */

 private static int sum(int i, int i0) {
     int c = i + i0;
     System.out.println("c:" + c);
     return c;
 }

 private static int sum(int i, int i0, int i1) {
     int c = i + i0 + i1;
     System.out.println("c:" + c);
     return c;
 }

}
Community
  • 1
  • 1
vajrakumar
  • 758
  • 2
  • 7
  • 21
  • 2
    What is your question? Is the question on how to do it with generics? If it's only about varargs, why did you ask, and provide an answer in a matter of seconds? – jlordo Jan 17 '13 at 08:44
  • jlordo: Actually many people don't know to use varArgs. I searched for this in net i couldn't find an answer so as I found solution posted it thinking it may be helpfull to others. @amit: yes that is what I wanted to share. Thanks for giving reference. – vajrakumar Jan 17 '13 at 09:25

4 Answers4

3

try comething like this

public int sum(int... args) {  
  int sum = 0;  
  for (int i : args)  
    sum += i;  
  return sum;  
}

then you can call

sum(3);
sum(3, 4, 5);
sum(3, 4, 5, 6, 7);

erit: amit was 5 sec quicker :)

ppeterka
  • 20,583
  • 6
  • 63
  • 78
Misiakw
  • 902
  • 8
  • 28
1

Try this :

public class Main
{
    public static void main(String[] argv)
    {
        int result1 = sum(1, 2);
        int result2 = sum(1, 2, 3);
        int result3 = sum(1, 2, 4, 5, 6, 1000);

        System.out.println(result1 + "\n" + result2 + "\n" + result3);
    }

    private static int sum(int... args)
    {
        int ret = 0;

        if (args != null)
        {
            for (int val : args)
            {
                ret += val;
            }
        }
        return ret;
    }
}
restricteur
  • 302
  • 5
  • 17
0

Quick approach

This could be a solution (note: always use meaningful variable names!):

private static int sum(int i, int... others) {
    int sum = i;

    if(others!=null)
        for(int other : others) {
            sum+=other;
        }
    }
    System.out.println("sum:" + sum);
    return sum;
}

Notice the arguments. As it is not very meaningful to sum 1 number, this construct ensures that there is at least 1 int coming in. And this one also checks for null value in the vararg.

Overflowing with emotions...

What would happen with the quick approach when executing this:

int veryBigNumber = sum(Integer.MAX_VALUE, 1);

veryBigNumber would in fact be ==Integer.MIN_VALUE...

This might be a problem. As Java does not throw an exception when an overflow occurs, you could end up with incorrect results. You could do a check for overflows:

private static int aLittleBitSaferSum(int i, int... others) throws ArithmeticException {
    int sum = i;
    if(others!=null)
        for(int other : others) {
            if(Integer.MAX_VALUE-other<sum) {
                throw new ArithmeticException("Sum would be too large to fit in int");
            }         
            if(Integer.MIN_VALUE+other>sum) {
                throw new ArithmeticException("Sum would be too small to fit in int");
            }         
            sum+=other;
        }
    }
    System.out.println("sum: " + sum);
    return sum;
}

Of course, this is just a dumb check... The result could fit very well in an int, for example with this:

sum(Integer.MAX_VALUE, 1, -1);

Which should result in Integer.MAX_VALUE - which it would wihtout the checks.

Extending the horizon

Fear not! The aforementioned problem could also be solved. For example, by providing a clever algorithm ordering the operands in a way that the partial result would always fit in the int range, but I think that is a problem not trivial to be solved... And would cost a lot in computing power.

However, by extending the range of the values the function is dealing with, it can do a lot better:

private static int aLittleBitSaferSum(int i, int... others) throws ArithmeticException {
    long sum = i;
    if(others!=null)
        for(int other : others) {
            if(Long.MAX_VALUE-other<sum) {
                throw new ArithmeticException("Sum would be too large for this algorithm to deal with");
            }         
            if(Long.MIN_VALUE+other>sum) {
                throw new ArithmeticException("Sum would be too small for this algorithm to deal with");
            }         
            sum+=other;
        }
    }

    if(Integer.MAX_VALUE<sum) {
        throw new ArithmeticException("Sum would be too large to fit in int");
    }         
    if(Integer.MIN_VALUE>sum) {
        throw new ArithmeticException("Sum would be too small to fit in int");
    }       

    System.out.println("sum: " + sum);
    return (int)sum;
}

This still has limitations, as long has too, but as long is twice the size of an Integer, it is far less likely to cause a problem. This is however a bit slower due to the extra work involved, also a lot less readable because of the checks.

I want it all

... and I want it now. The range can still be a problem, this is a solution to it:

private static int aSafeButSlowerSum(int i, int... others) throws ArithmeticException {
    BigInteger sum = BigInteger.valueOf(i);
    BigInteger intMax = BigInteger.valueOf(Integer.MAX_VALUE); //should be a private static final class variable
    BigInteger intMin = BigInteger.valueOf(Integer.MIN_VALUE); //should be a private static final class variable

    if(others!=null)
        for(int other : others) {
            sum=sum.add(BigInteger.valueOf(i));
        }
    }

    if(intMax.compareTo(sum)<0) {
        throw new ArithmeticException("Sum would be too large to fit in int");
    }         
    if(intMin.compareTo(sum)>0) {
        throw new ArithmeticException("Sum would be too small to fit in int");
    }       

    System.out.println("sum: " + sum.toString());
    return sum.intValue;
}

This is even slower due to all the BigInteger stuff, but shows no problems of the above functions. (so it will be a little bit less "now" as with the other options, but there is a price to pay for the extras..)

BenMorel
  • 34,448
  • 50
  • 182
  • 322
ppeterka
  • 20,583
  • 6
  • 63
  • 78
-1
public static void main(String[] arg) {
    int result2 = sumVarArgs(1, 2);
    System.out.println(result2);
    int result3 = sumVarArgs(1, 2, 3);
    System.out.println(result3);
    int result4 = sumVarArgs(1, 2, 3, 4);
    System.out.println(result4);
    int result5 = sumVarArgs(1, 2, 3, 4, 5);
    System.out.println(result5);

}


    /**
     * Aoccepts an all int variables and conciders them as an array and adds
     * them
     *
     * @param argsAry multiple number of input parameters having data type
     * <i>int</i>
     * @return sum of all passed int variables in int format
     */
public static int sumVarArgs(int... argsAry) {
     int c = 0;
     for (int i = 0; i < argsAry.length; i++) {
         c += argsAry[i];
     }
     return c;
}
amit
  • 175,853
  • 27
  • 231
  • 333
vajrakumar
  • 758
  • 2
  • 7
  • 21
  • 3
    Note that the code is not null safe. Have a look on the code provided by @restricteur, this is how it should be done – amit Jan 17 '13 at 08:59