用于传递和调用方法引用的Lambda语法

时间:2015-08-26 00:07:23

标签: java lambda enums

传递和调用方法引用的 Lambda语法是什么?

场景:根据Enum中的值构建对象(单选按钮)。

我传递了枚举值的集合。我希望另一个方法(构造函数)在每个枚举值上调用一个方法。该方法调用确定每个单选按钮的显示标签。

但该方法的名称因每个特定的Enum类而异。一些枚举有getTitle方法,另一个可能有getDescriptiongetCaption方法,而另一个可能有getLocalizedVariationOfTitle。如何让每个调用程序员调用他们的特定方法?

Collection<SomeEnum> enumValues = Arrays.asList( SomeEnum.values() );
x = new EnumRadioButtons( enumValues , ??methodReferenceToGetTitle?? );

传递和调用??methodReferenceToGetTitle??的语法使我望而却步。构造函数如下所示:

public EnumRadioButtons ( Collection<?> options , ??methodReferenceToGetTitle?? ) {
    …
    for ( Object option : options ) {
        this.setTitleOfEachOption( option , ??methodReferenceToGetTitle?? );
    }
}

取消引用方法引用时,代码实际上变为:

this.setTitleOfEachOption( option , option.getTitle() );  // Pass the radio button item, and its label text.

或:

this.setTitleOfEachOption( option , option.getDescription() );

或:

this.setTitleOfEachOption( option , option.getSomeLocalizedVariationOfTitle() );

我尝试将MyEnum::getTitle传递给名为MyEnum的枚举,确实有一个方法getTitle()。但是我遇到编译器错误。

我预感这个答案可能会使用Supplier

public EnumRadioButtons ( Collection<?> options , java.util.function.Supplier<String> supplierOfTitle ) {
    super( caption , options );
    for ( Object option : options ) {
        this.setTitleOfEachOption( option , supplierOfTitle.get() );
    }
}

作为一种解决方法,我可以要求每个枚举实现TitleGetable的接口,例如:

public interface TitleGetable
{
    public String getTitle ();
}

但让所有调用程序员携带并明确实现这个额外的接口似乎很愚蠢。鉴于这是一个只返回一个String的方法,看起来它似乎是在寻求简单的Lambda语法。

1 个答案:

答案 0 :(得分:4)

当您希望用户能够使用lambda语法时,您所要做的就是获取一个参数,该参数只是一个抽象函数的接口。
调用者决定使用方法引用,lambda与
 () - &gt;样式或只是像常规的pre-java 8接口一样实现接口。为方便起见,java.util.function中有几个预定义的。

为了更好的类型安全,最好使用泛型而不是原始集合。

这是一个定义。

class EnumRadioButtons<T> {

    public EnumRadioButtons(Collection<T> options, Function<T,String> f ) {
        for (T option : options) {
            this.setTitleOfEachOption(option, f.apply(option));
        }
    }

    public void setTitleOfEachOption(T option, String title) {
          System.out.println("DEBUG - Setting title of option: " + option  + " to have title of: " + title );
    }
}

例如,可以使用此枚举:

enum MyEnum {
    A,B,C;

    public String myToString() {
        return toString();
    }
}

...以及此main方法类:

class User {
    public static void main(String[] args) {

        EnumRadioButtons<MyEnum> bts 
                = new EnumRadioButtons<>(Arrays.asList(MyEnum.values()),
                        MyEnum::myToString); // user of method reference
    }
}