求解释Vaadin/Spring Boot示例代码中Lambda表达式的工作原理
关于Vaadin Grid中Lambda表达式的用法解释
问题背景
- 学习Vaadin/Spring Boot相关教程,Java学习时长1年左右,对示例中的Lambda写法逻辑不理解,观看教程视频后仍未理清运行规则
- 涉及的示例代码如下:
private void configureGrid() { grid.addClassName("contact-grid"); grid.setSizeFull(); grid.setColumns("firstName", "lastName", "email"); grid.addColumn(contact -> contact.getStatus().getName()).setHeader("Status"); grid.addColumn(contact -> contact.getCompany().getName()).setHeader("Company"); grid.getColumns().forEach(col -> col.setAutoWidth(true)); }
核心概念前置说明
Lambda是Java 8推出的语法糖,核心作用就是把一段要执行的逻辑直接当参数传给方法,省去了以前写匿名内部类实现接口的大量样板代码。它能用的前提是,方法参数要求的类型是「函数式接口」——也就是只定义了一个抽象方法的接口,Lambda就是用来快速实现这个唯一抽象方法的。
不用死记复杂概念,对着代码里的三个Lambda逐行拆解就很容易理解:
逐行解释Lambda的逻辑和作用
1. contact -> contact.getStatus().getName()
这行是传给grid.addColumn()方法的参数。addColumn方法要求传入一段逻辑,告诉Grid:这一列要从每行绑定的对象里取什么值显示。
- 箭头左边的
contact:是Grid渲染每一行时,自动传给这段逻辑的当前行绑定的Contact实体对象,不需要手动传参,框架渲染到哪行就自动把哪行的对象塞进来 - 箭头右边的逻辑:拿到当前行的contact对象后,取它关联的Status状态对象的name属性,把这个值返回给Grid,Grid就会把这个值显示在"Status"列的对应单元格里
- 后面链式调用的
.setHeader("Status")只是给这列设置表头文本,和Lambda逻辑无关
2. contact -> contact.getCompany().getName()
逻辑和上面完全一致:告诉Grid,这一列每一行要显示当前contact关联的Company公司的name属性值,表头设为"Company"。
如果是Java 8之前没有Lambda的写法,上面这两列要写很长的匿名内部类代码,比如:
grid.addColumn(new ValueProvider<Contact, String>() { @Override public String apply(Contact contact) { return contact.getStatus().getName(); } }).setHeader("Status");
Lambda就是把冗余的接口声明、方法重写声明全砍掉了,只留最核心的入参和执行逻辑,代码简洁度提升非常明显。
3. col -> col.setAutoWidth(true)
这行是传给集合forEach遍历方法的参数。forEach方法要求传入一段逻辑,告诉集合:遍历到每个元素的时候要对它做什么操作。
- 箭头左边的
col:是遍历Grid所有列的时候,依次拿到的每一个列对象 - 箭头右边的逻辑:给当前遍历到的列设置自动宽度属性为true,最终效果就是表格所有列都会根据内容自动适配宽度。
运行逻辑总结
你写的这些Lambda代码,不需要自己手动调用。把逻辑传给对应的方法后,会由框架或者JDK的集合工具在合适的时机自动回调:
- 表格渲染阶段,Vaadin逐行逐列渲染时,会自动回调你传给
addColumn的Lambda,拿到每个单元格要显示的内容 - 执行
forEach时,集合遍历到每一列,就会自动回调你传的Lambda,完成列宽设置
内容的提问来源于stack exchange,提问作者njsour
相关产品推荐
相关产品推荐

