java中的lambda 表达式

背景:

学java断断续续也有三年了吧,一直没有弄清楚lambda表达式,正好最近刷题时遇到一道题。原题如下:

image.png

这道题本身是一道十分简单的题,将第一个数组放入一个hashSet,然后遍历第二个数组,将重合的数字再放入第二个hashSet,最后将hashSet转成int数组返回就完成了,当然,解法不唯一。


写完后我就在想将数组放入hashSet是不是非要用for循环遍历呢?于是我去看了hashSet的构造函数,发现可以传一个集合过来进行初始化,那问题又来了,如何把一个数组转成集合,如果数组里面不是基本数据类型而是对象,比如String[],就可以使用Arrays.asList()来转,但是这里是int数组。

我在网上看到了使用stream进行数据类型转换,比如这里就可以使用Arrays.stream(数组).boxed().collect(Collectors.toCollection(HashSet::new))将int数组转成hashSet,我再去了解java stream,发现这个功能是java 8新加的,而且是基于lambda表达式的,所以我这次详细了解了一下lambda表达式,整理在后文方便随时温习。顺便提一句大家了解完lambda表达式也可以去看看stream。

lambda表达式

首先lambda表达式是用来干啥的
lambda表达式,即带有参数的表达式,也有很多人喜欢说它是匿名类的优雅实现方式,确实,这是它给人的直观感受。或者更明确一点来说,把一个值赋给一个变量是我们大家都熟知的java变量使用,而lambda表达式则是把一块代码赋给一个变量,如下图:

image.png

这样是不是就比较具体了?Test是一个函数式接口,如果不知道什么是函数式接口,暂且可以在这里把它想象成一个接口,lambda表达式就是对这个抽象接口的实际实现,里面的方法体就是实现的接口里面那个未实现的方法,所以你也就该猜想函数式接口里只有一个未实现的方法,现在你可以这样认为。所以lambda表达式做了什么是不是就一目了然了?之后再去了解下lambda表达式的语法,相信大家都可以写出符合自己需求的lambda表达式。像我上图展示的那样,之后我就可以直接用lam1这个变量调用接口里定义的那个方法来使用了,是不是还是挺有意思。
lambda表达式分为不含参、含单参、含多参几种情况,但在操作上其实都大同小异,网上的介绍也很多,我这里就不细说了。http://www.cnblogs.com/andywithu/p/7357069.html这篇就写得还算详细。

方法引用

在lambda表达式中还有几个点要说一下,分别是方法引用和构造器引用,这两个很类似,所以我在这里只说方法引用。

方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法。方法引用提供了一种引用而不执行方法的方式,它需要由兼容的函数式接口构成的目标类型上下文。计算时,方法引用会创建函数式接口的一个实例。

方法引用的符号是::,说白了就是在lambda表达式中通过类名或者对象名调用方法的简洁方式。

同样的,知道了它是什么我们就来说说怎么使用它。
方法引用共分为四类:
1.类名::静态方法名
2.对象::实例方法名
3.类名::实例方法名
4.类名::new
用法都是类似的,我们举一个具体的例子应该就能明白。
这个例子是在其他地方看到的,正好拿过来举例,在此说明。

public class StudentComparator {
public int compareStudentByScore(Student student1,Student student2){
return student2.getScore() - student1.getScore();
}
}

StudentComparator studentComparator = new StudentComparator();
students.sort(studentComparator::compareStudentByScore);
students.forEach(student -> System.out.println(student.getScore()));

StudentComparator中定义了一个非静态的,实例方法compareStudentByScore,同样该方法的定义满足Comparator接口的compare方法定义,所以这里可以直接使用 对象::实例方法名 的方式使用方法引用来替换lambda表达式。集合排序的时候需要传入比较的方法,这里通过方法引用将compareStudentByScore方法作为比较方法给了排序方法。是不是就很清晰了,但是要注意,Comparator接口本身是一个函数式接口,所以这里可以正常使用,如果没有函数式接口是不满足使用lambda表达式的先决条件的。我之前就是乱用结果编辑器一直给我报错,弄得我很崩溃。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 作者:Sevenvidia链接:https://www.zhihu.com/question/20125256/a...
    邪影oO阅读 3,966评论 5 5
  • Java8中新增了一个默认的方法。 这个默认方法的目的是在接口中可以实现方法,而且不强制要求实现类去实现这个方法,...
    lurenjia阅读 12,498评论 0 1
  • Java 课堂上没有讲的知识 Lambda函数 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数...
    sayonara_yoyo阅读 2,828评论 0 0
  • 一树梨棠暖,半盏花颜瘦。 只道春来不是秋,一抹斜阳空留。 花间草堂琉球,青砖方塘毓秀。 莫等故人误白首,空余梨花独...
    松子果果阅读 5,195评论 9 15
  • “你就是理想主义!”昨晚先生丢过来一句话。听完这句对我的评论,眯眯笑着回答说:“我确实理想主义,喜欢唯美的...
    羽西随笔阅读 3,663评论 0 2

友情链接更多精彩内容