Suggest the following:
Consumer<Object[]> consumer = (args) -> { /* Do something */ }
To make use of the consumer, I have to create an Object array. So, I'd have to write something like
consumer.accept(new Object[]{ object0, object1, ... });
Obviously, I'd rather have something like
Consumer<Object...> consumer = (args) -> { /* Do something */ }
consumer.accept(object0, object1, ...);
Is something like this possible?
CodePudding user response:
But you can create your own functional interface as follows:
interface IntVarArgsConsumer {
void accept(int ...s);
}
IntVarArgsConsumer printArray = arr-> System.out.println(Arrays.toString(arr));
printArray.accept(1,2,3,4,5);
printArray.accept(1,2,3);
prints
[1, 2, 3, 4, 5]
[1, 2, 3]
But I caution you not to mix generic type parameters
and varargs
. Otherwise you can pollute the heap and get ClassCastExceptions
. If you just want to process Strings
, then use the String
type. If Objects
, use the Object
type. But not some type R
as you might see in other methods.
CodePudding user response:
Variable arity parameter (varargs) is a syntactic element, a special token indicating that a method (or a constructor) expects 0
or more arguments of that type. And these arguments will be wrapped by an array (so that technically they will constitute a single argument) when the method gets executed.
Its usage is limited: a method can have only one parameter of variable arity and it must be defined in the last position.
Variable arity parameter isn't a type by itself. If you'll try to use eclipses ...
anywhere apart from the last position of a method (constructor) declaration, you'll get a compile error (take a look at JLS for more information).
In order to use a variable number of arguments in a function, you can define a functional interface with a method of variable arity. And this method is the only place where elipses ...
needs to be used.
@FunctionalInterface
public interface MyConsumer<T> {
void accept(T... items);
}
MyConsumer<String> myConsumer = items -> Stream.of(items).forEach(System.out::println);
myConsumer.accept("A", "B", "C");
Will give an output:
A
B
C