It's possible if you define such a functional interface with multiple type parameters. There is no such built in type. (There are a few limited types with multiple parameters.)
@FunctionalInterface
interface Function6<One, Two, Three, Four, Five, Six> {
public Six apply(One one, Two two, Three three, Four four, Five five);
}
public static void main(String[] args) throws Exception {
Function6<String, Integer, Double, Void, List<Float>, Character> func = (a, b, c, d, e) -> 'z';
}
I've called it Function6 here. The name is at your discretion, just try not to clash with existing names in the Java libraries.
There's also no way to define a variable number of type parameters, if that's what you were asking about.
Some languages, like Scala, define a number of built in such types, with 1, 2, 3, 4, 5, 6, etc. type parameters.
Answer from Sotirios Delimanolis on Stack OverflowIt's possible if you define such a functional interface with multiple type parameters. There is no such built in type. (There are a few limited types with multiple parameters.)
@FunctionalInterface
interface Function6<One, Two, Three, Four, Five, Six> {
public Six apply(One one, Two two, Three three, Four four, Five five);
}
public static void main(String[] args) throws Exception {
Function6<String, Integer, Double, Void, List<Float>, Character> func = (a, b, c, d, e) -> 'z';
}
I've called it Function6 here. The name is at your discretion, just try not to clash with existing names in the Java libraries.
There's also no way to define a variable number of type parameters, if that's what you were asking about.
Some languages, like Scala, define a number of built in such types, with 1, 2, 3, 4, 5, 6, etc. type parameters.
For something with 2 parameters, you could use BiFunction. If you need more, you can define your own function interface, like so:
@FunctionalInterface
public interface FourParameterFunction<T, U, V, W, R> {
public R apply(T t, U u, V v, W w);
}
If there is more than one parameter, you need to put parentheses around the argument list, like so:
FourParameterFunction<String, Integer, Double, Person, String> myLambda = (a, b, c, d) -> {
// do something
return "done something";
};
Videos
The correct syntax would in your case be:
interface Implementable{
public ReturnObj doIt(Object... objs);
}
Official documentation for var-arg methods is found here.
I was about to ask the difference between varargs and passing an array,
Varargs gets compiled into an argument of an array-type. The only difference is with the vararg syntax, method calls such as
doIt("hello", "world");
will be compiled into
doIt(new Object[] { "hello", "world" });
In other words, given a declaration such as
public ReturnObj doIt(Object[] objs);
you'll have
doIt(new Object[] { "hello", "world" }); // works fine
doIt("hello", "world"); // won't compile
while given the var-arg declaration, both method calls will compile and be equivalent.
Pass an array:
public ReturnObj doIt(Object[] input);
or use the equivalent varargs expression
public ReturnObj doIt(Object... input);
The solution depends on the answer to the question - are all the parameters going to be the same type and if so will each be treated the same?
If the parameters are not the same type or more importantly are not going to be treated the same then you should use method overloading:
public class MyClass
{
public void doSomething(int i)
{
...
}
public void doSomething(int i, String s)
{
...
}
public void doSomething(int i, String s, boolean b)
{
...
}
}
If however each parameter is the same type and will be treated in the same way then you can use the variable args feature in Java:
public MyClass
{
public void doSomething(int... integers)
{
for (int i : integers)
{
...
}
}
}
Obviously when using variable args you can access each arg by its index but I would advise against this as in most cases it hints at a problem in your design. Likewise, if you find yourself doing type checks as you iterate over the arguments then your design needs a review.
Suppose you have void method that prints many objects;
public static void print( Object... values){
for(Object c : values){
System.out.println(c);
}
}
Above example I used vararge as an argument that accepts values from 0 to N.
From comments: What if 2 strings and 5 integers ??
Answer:
print("string1","string2",1,2,3,4,5);
Function<Integer,Integer,Integer> f3 = (x,y) -> {return x + y};
is actually a BiFunction<Integer,Integer,Integer>
and
Function<Double> f4 = () -> {return Math.random()};
is a Supplier<Double>
If you need more create your own, like TriFunction<Integer,Integer,Integer,Integer> for example
I am almost sure that you can define own functional interface (i.e., create a new file commonly) to develop f3 and f4, but Is there some way to easily define them?
In addition to the Eugene answer, I would add that :
Function<Integer,Integer,Integer> f3 = (x,y) -> {return x + y};
may be considered as BiFunction<Integer,Integer,Integer> or simply BinaryOperator<Integer>.
Note that you perform arithmetical computations with the Integers in the lambda body. These produce unboxing and boxing operations : Integer->int->Integer. So in this use case you are encouraged to use a specialized functional interface that prevents that : IntBinaryOperator which the functional signature is (int, int)-> int that is itself a specialization of BinaryOperator<T> a subclass of BiFunction<T,T,T>
In the same logic of sparing autoboxing operations :
Function<Integer,Integer> f2 should be IntFunction f2
and Supplier<Double> f4 should be DoubleSupplier f4.
Note also that specifying a specific number of argument makes sense as it is straight usable in a lambda body but specifying something like a var-args is possible but generally harder to exploit.
For example you could declare this interface :
@FunctionalInterface
public interface VargsFunction<T,R> {
@SuppressWarnings("unchecked")
R apply(T... t);
}
But harder to use without delegating to a method that accepts a var-args :
VargsFunction<Integer, Integer> f = varg-> call(varg);
Integer call(Integer... varg) {
...
}
This is done using a BiFunction<T,U,R>. Following is an example of a BiFunction returning the character at the specified index of a String:
BiFunction<String, Integer, Character> charAtFunction = (string, index) -> string.charAt(index);
Try :
BiFunction<Integer, Integer, String> lambda = (a, b) -> ("Given values are " + a + ", " + b);
You can have a method which takes Object which is any type. In Java 5.0 and later primitives will be auto-boxed and passed as an object as well.
void method(Object o);
can be called using
method(1);
method("hello world");
method(new MyClass());
method(null);
If I understand correctly, you're asking if a method foo() can have multiple different inputs for its parameters
That way foo(Integer i) and foo(String s) are encased in the same method.
The answer: yes, but it's not pretty
foo(Object o)
Is your method declaration
Now you need to sort out the different types of possibilities
if(o instanceof Integer){
stuff();
} else if (o instanceof String){
moreStuff();
}
Just chain those else/if statements for the desired result.