Home > Blockchain >  Consumer with varargs
Consumer with varargs

Time:04-25

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
  • Related