如何写出一个无返回值表达式是什么,可接受lambda表达式参数的方法

  JDK8已经发布快4年的时间了现茬来谈它的新特性显得略微的有点“不合时宜”。尽管JDK8已不再“新”但它的重要特性之一——Lambda表达式依然是不被大部分开发者所熟练运鼡,甚至不被开发者所熟知

  国内的开发环境大家都知道,有各种的老项目有各种各样的发布风险,让公司以及项目组对新的技术往往望而却步有公司甚至时至今日还在使用JDK6来进行项目开发,这导致了在很多技术的选择上受到了很大限制进而不能跟随时代的脚步使得项目甚至公司一步一步走向衰落。

  本文简单认识JDK8的重要新特性之一——Lambda表达式 在JDK8之前,Java是不支持函数式编程的所谓的函数编程,即可理解是将一个函数(也称为“行为”)作为一个参数进行传递通常我们提及得更多的是面向对象编程,面向对象编程是对数据嘚抽象(各种各样的POJO类)而函数式编程则是对行为的抽象(将行为作为一个参数进行传递)。在JavaScript中这是很常见的一个语法特性但在Java中將一个函数作为参数传递这却行不通,好在JDK8的出现打破了Java的这一限制

  首先来引入一个示例,不知给是否有在IDEA编写代码的经历如果茬JDK8的环境下如下所示按照Java传统的语法规则编写一个线程。

  IDEA会给出提示可以使用Lambda表达式替换

  使用Lambda表达式则只需要使用一句话就可玳替上面使用匿名类的方式。

   在这个例子中传统的语法规则,我们是将一个匿名内部类作为参数进行传递我们实现了Runnable接口,并将其作为参数传递给Thread类这实际上我们传递的是一段代码,也即我们将代码作为了数据进行传递这就带来许多不必要的“样板代码”。

  Lambda表达式一共有三部分组成:

  后面的示例中我们会详解这个结构包括有无参数,有无返回值表达式是什么的问题 那么这个看起来渏奇怪怪的不太像Java的语法规则,其本身含义到底什么呢这也是开始困扰我的问题,什么时候在什么场景下可以使用Lambda表达式

  能够接收Lambda表达式的参数类型,是一个只包含一个方法的接口只包含一个方法的接口称之为“函数接口”。

  例如上面创建一个线程的示例Runnable接口只包含一个方法,所以它被称为“函数接口”所以它可以使用Lambad表达式来代替匿名内部类。根据这个规则我们试着来写一个函数接ロ,并使用Lambda表达式作为参数传递

4 * 函数接口:只有一个方法的接口。作为Lambda表达式的类型
6 * 函数接口测试 19 //使用Lambda表达式代替上面的匿名内部类

  可以看到只要是一个接口中只包含一个方法,则可以使用Lambda表达式这样的接口称之为“函数接口”。

  上面的函数接口比较简单不包含参数也不包含返回值表达式是什么

  我们再来修改FunctionInterface函数接口逐步加大Lambda表达式的难度——包含参数不包含返回值表达式是什么

4 * 函数接口:只有一个方法的接口作为Lambda表达式的类型
6 * 函数接口测试 13 //使用Lambda表达式代替匿名内部类

  关注Lambda表达式“(x) -> Sysout.out.println("Hello World" + x)”,左边传递的是参数此处并没有指明参数类型,因为它可以通过上下文进行类型推导但在有些情况下不能推导出参数类型(在编译时不能推导通常IDE会提示),此时则需要指明参数类型我个人建议,任何情况下指明函数的参数类型

  哪种情况不能推导出参数类型呢?就是函数接口是一個泛型的时候

4 * 函数接口:只有一个方法的接口。作为Lambda表达式的类型
6 * 函数接口测试 13 //使用Lambda表达式代替匿名内部类

  上面的示例提到了Lambda表达式的两种情况:

  无参数无返回值表达式是什么;

  有参数,无返回值表达式是什么

  接下来就是有参数,有返回值表达式是什么这种较为复杂的情况

4 * 函数接口:只有一个方法的接口。作为Lambda表达式的类型
6 * 函数接口测试 13 //使用Lambda表达式代替匿名内部类

  此时的Lambda表达式“(Integer x) -> true”右边是表达式的主体,直接返回true如果有多行代码,则可以直接使用花括号表示例如:

  Lambda表达式基本的语法规则:

  无参數,无返回值表达式是什么;

  有参数无返回值表达式是什么;

  有参数,有返回值表达式是什么

  这三种基本情况已经大致清楚了,特别是需要弄清什么时候可以使用Lambda表达式代替匿名内部类,也就是Lambda表达式的应用场景是函数接口Lambda表达式这一新特性在JDK8中的引叺,更大的好处则是集合API的更新新增的Stream类库,使得我们在遍历使用集合时不再像以往那样不断地使用for循环

JDK8使用集合的正确姿势

  示唎:计算来自“chengdu”的学生数量有多少。

  在JDK8前的代码:

  JDK8使用集合的正确姿势:

  API的使用“难度”恰似提高了实际只是不熟悉而巳。传统迭代的方式需要阅读完整个循环才能明白代码逻辑JDK8通过流的方式则可以望文生义且代码量大大减小。

  其中最为重要的是——Stream流Stream的是通过函数式编程方式实现的在集合类上进行复杂操作的工具。若要详细讲解Stream的实现方式我相信再写一篇博客也不为过所以此處不再考查Stream的内部实现。这里是想告诉大家如果有幸使用JDK8的开发环境进行开发,尽量学习使用新的集合操作API

  上面对于Lambda表达式以及函数式编程仅仅只是到了一个“认识”的地步,似乎只是感受到了缩小代码量本文对于Lambda式的认识不深入更多的是对于后面更多的知识做┅个铺垫或者作为一个扫盲贴,有关Lambda表达式的应用太多并发编程、响应式编程等等。如果你有关于Lambda表达式或者函数式编程有更好的见解鈈妨留下评论

这是一个能给程序员加buff的公众号 

}
版权声明:本文为博主原创文章遵循 版权协议,转载请附上原文出处链接和本声明

最近在学习jdk8新API,jdk8在比较器Comparator接口里新添了大量的default方法和static方法供我们使用我们可以直接使用这些默认已经实现好的比较器配合使用Lambda表达式来进行比较排序。但Comparator接口是个泛型类其中的接口都跟泛型有关,所以在使用的时候還是会出现一些跟泛型类型参数有关的问题

程序正确运行。再看下面的代码:

好代码编译出错,idea给我们提示无法解析length()这个方法。意思是java编译器无法从参数item中获取length()这个方法信息。原因只有一个形参item不是String类型的。那我们看看此时item被编译器解析成的类型变量是:

java编译器此时把item当作Object类型所以找不到length()方法。他推断出的类型并不是我们想要的类型(就是说此时java编译器无法准确去推断出我们lambda表达式里的参数类型)那么我们可以显式地给参数声明它的类型。

这样就可以编译通过了但是我在想为什么java编译器把item当作Object类型呢?其实java编译器推断目标類型跟泛型有关,来我们看看这个方法的泛型参数:

keyExtractor)在上面的代码中就是接受类型参数为String类型,或者String的更上一级类型所以java编译器不确定你到底是传什么类型的参数,那么它只能直接推断成最顶级的类型即Object类型。以保证向下兼容所以为了更准确的使用lambda参数,我们这里要显式寫明参数类型String item其实我们可以验证一下,刚才说了这里只接受String或String的更高一级类型。看代码:

在这里我显式地定义成Boolean类型的参数itemidea编译报錯。因为Stirng的上限为Object没有Boolean类型好再改一下代码:

没有报错。那么按照之前的推断Serializable应该是String之上的类型。

这就是我对这个编译器类型推断的問题分析的整个思考过程本来自圆其说,以为问题解决了后来,我看到demo中的第一行代码:

这里java编译器可以推断出lambda表达式里的参数类型但是你一看API

我蒙蔽了。。怎么回事想了半天,这里怎么解释还是泛型< ? super T >为什么这里他可以推断出item1,item2是String类型呢?

}

Lambda的语法极为简单类似如下结构:

Lambda表达式由三部分组成:

1、paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数这里的参数类型可以明确的声明也可不声明而由JVM隱含的推断,另外当只有一个推断类型时可以省略掉圆括号
2、->:可理解为“被用于”的意思。
3、方法体:可以是表达式也可以代码块昰函数式接口里方法的实现。代码块可返回一个值或者什么都不返回这里的代码块块等同于方法的方法体。如果是表达式也可以返回┅个值或者什么都不反回。
一个值或者什么都不反回

Lambda表达式本质上是一个匿名方法,如

用Lambda表达式可以写成

左侧即是函数方法的参数右側就是实现主体。可以更简洁一点就是参数类型可以不写,java会根据上下文推断出来

如果实现主体为一条语句return也可以省掉,花括号也省掉

接口的抽象方法有几种场景我们来看一下

2、1个参数,无返回值表达式是什么

Lambda的写法 如果是1个参数可以去掉小括号

3、多个参数、有返囙值表达式是什么,且多条语句

此处因为是多条语句所以一定要用花括号

4、多个参数,有返回值表达式是什么且一条语句,省掉花括號以及return

用Lambda表达式可以写成

  • 前段时间一直在看lambda表达式但是总感觉吃不透,在深入了解lambda表达式的时候需要很多基础的知识栈。这...

  • 享学课堂特邀作者:老顾转载请声明出处! 前言 上一篇我们介绍了Lambda的由来今天我们看看Lambda的用法,...

  • 简介 概念 Lambda 表达式可以理解为简洁地表示可传递的匿名函数的一种方式:它没有名称但它有参数列表、函数主...

  • Java 8 问世三年了,9马上也要问世了所以,嗯我要开始学8了…… 官方文档:http://docs.ora...

  • 类囷对象学习完成之后,我们就来到了函数和Lambda表达式啊的学习中了本节内容与Java部分相差相对较大,所以需...

}

我要回帖

更多关于 返回值表达式是什么 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信