Scala 2.12中实现Java双冒号(::)等价写法改写Vaadin Grid代码
Scala 2.12 下 Vaadin Grid Java 代码的改写方案
原Java代码回顾
Grid<Person> grid = new Grid<>(Person.class, false); grid.addColumn(Person::getFirstName).setHeader("First name"); grid.addColumn(Person::getLastName).setHeader("Last name");
对应的Grid方法签名(已翻译):
public Column<T> addColumn(ValueProvider<T, ?> valueProvider) { BiFunction<Renderer<T>, String, Column<T>> defaultFactory = getDefaultColumnFactory(); return addColumn(valueProvider, defaultFactory); }
这里ValueProvider<T, ?>是Java函数式接口,作用是接收T类型参数并返回任意类型结果。
Scala 2.12 改写方式
Scala 2.12支持SAM转换(单抽象方法转换),可直接将Scala的lambda表达式或方法引用适配为Java的函数式接口,以下是几种可行写法:
写法1:匿名函数(最简洁直观)
val grid = new Grid[Person](classOf[Person], false) grid.addColumn(_.getFirstName).setHeader("First name") grid.addColumn(_.getLastName).setHeader("Last name")
这里_.getFirstName是Scala占位符语法,和Java的Person::getFirstName实例方法引用语义完全一致,会自动转换为ValueProvider[Person, String]。
写法2:显式声明ValueProvider实例
如果需要明确类型标注,可手动实现:
import com.vaadin.flow.data.provider.ValueProvider val grid = new Grid[Person](classOf[Person], false) val firstNameProvider: ValueProvider[Person, String] = (p: Person) => p.getFirstName grid.addColumn(firstNameProvider).setHeader("First name") grid.addColumn((p: Person) => p.getLastName).setHeader("Last name")
写法3:Scala原生方法引用语法
若Person类在Scala中定义,或需复用已有方法,可使用Scala的方法引用:
// 假设Person的getFirstName为def类型方法 val grid = new Grid[Person](classOf[Person], false) grid.addColumn(Person.getFirstName _).setHeader("First name") grid.addColumn(Person.getLastName _).setHeader("Last name")
注意此处需加下划线_,明确表示是方法引用而非直接调用方法。
关键说明
- Scala 2.12的SAM转换无需额外导入转换工具(如Scala 2.11及更早版本依赖的
JavaConverters/JavaConversions),可直接适配Java函数式接口。 - 占位符语法
_.getXxx是最推荐的写法,和Java实例方法引用的逻辑完全匹配,用于提取实例属性值。
内容的提问来源于stack exchange,提问作者TiN
相关产品推荐
相关产品推荐

