Search code examples
javalambdafunctional-programmingfunctional-interface

How to create enum with BiConsumer<R, T> as constructor parameter


I would like to create enum class, with BiConsumer as constructor parameter. If I did it like this, everything works ok

public enum BiConsumerEnum {

    BI_CONSUMER(((Integer i, String s) -> Collections.nCopies(i, s).forEach(System.out::println)));

    private BiConsumer<Integer, String> biConsumer;

    public static void main(String[] args) {
        BiConsumerEnum.BI_CONSUMER.accept(3, "X");
    }

    BiConsumerEnum(BiConsumer<Integer, String> biConsumer) {
        this.biConsumer = biConsumer;
    }

    public void accept(Integer i, String s) {
        this.biConsumer.accept(i, s);
    }
}

But if change code to this:

public enum BiConsumerEnum {

BI_CONSUMER((Integer i, String s) -> printString());

// main(), constructor and accept()

private static BiConsumer<Integer, String> printString() {
    return (Integer i, String s) -> Collections.nCopies(i, s).forEach(System.out::println);
}

The code doesn't run properly and I've got warning: return value is never used

How should I extract method from constructor, instead of writing whole lambda inside?


Solution

  • Though the fix has been suggested by Sotirios Delimanolis in comments already, yet to elaborate that further your current code representation:

    BI_CONSUMER((Integer i, String s) -> printString());
    

    would compile successfully since you have defined a new BiConsumer such that your code's actual definition is now:

    BI_CONSUMER(new BiConsumer<Integer, String>() {
        @Override
        public void accept(Integer i, String s) {
            printString(); // has a return value, but is it used?
        }
    });
    

    and do note in the above that the return type of printString is not being used. What you possible intended there was to rather use the returned BiConsumer<Integer, String> from the existing method printString and invoke it as:

    BI_CONSUMER(printString());