对于上次【http://www.cnblogs.com/webor2006/p/8186039.html】已经初步引入的Java8中Stream流的概念,其中使用了map的操作,它需要接受一个Function这样的函数式接口,回顾一下:

而这次专门对Function这个函数式接口进行进一步学习,因为这个函数式接口是比较重要的,先查看一下该接口的javadoc:

另外还有三个方法,两个默认方法、一个静态方法:

乍一看这些具体实现的方法貌似写得挺复杂的,各种泛形,所以前期会仔细的一个个去学习,待熟悉之后,对于之后再看到类似的实现理解起来就比较容易了,得循序渐进~

下面来实例化一个Function,还是用之前转大写的那个方式来创建:

其中有个注意的地方在上次已经说明了,这里再强调一下:

其实也很好理解,因为toUpperCase是String类中的实例方法,要想调用这个方法必定是String的实例对象去调用,所以这里可以总结一个套路:如果说是通过类这个类型后面跟着"::"之后引用的是一个类的实例方法(如:String::toUpperCase),那么,它所对应Lambda表达式的第一个参数就是调用这个方法的那个对象。当然这是未来要学习的方法引用(Method References)的创建形式之一,这里也先有个印象既可。

下面引用一个新的字符串排序的例子,将一个集合中的字符串按钮倒序排序输出,这里先用传统的方式来实现:

查看一下Comparator源码:

所以,这里改用Lambda表达式来编写:

这时看一下提示:

按照提示的做法如下:

但是由于这种建议的方式脱离了我们想要学习的Lambda表达式,所以还是将其还原成Lambda方式,置灰忽略~

其实对于目前写的这种Lambda表达式是可以简单化的,看:

如下:

还可以继续简化,对于Lambda表达式的语句体目前就一句话,可以简化为:

那上面的这些演变规则是怎么样的呢?这里继续对Lambda表达式进行一个文字总结,看完之后就晓得上面的演变过程啦:

Lambda表达式作用:

  • 传递行为,而不仅仅是传值
  • 提升抽象层次
  • API重用性更好
  • 更加灵活

Java Lambda基础语法:

  • Java中的Lambda表达式基本语法:(argument) -> {body}
    比如说:
      (arg1, arg2...) -> {body}
      (type1 arg1, type2 arg2...) -> {body}

Java Lambda示例:

  • (int a, int b) -> {return a + b;}
    接收两个整型参数,并返回一个整数。
  • () -> System.out.println("hello world");
    不接收参数,也不返回值,打印hello world。
  • (String s) -> {System.out.println(s);}
    接收一个字符串,并打印出该字符串,不返回值。
  • () -> 42
    无参数,返回42。
  • () -> {return 3.1415};
    无参数,返回3.1415。

Java Lambda结构:

  • 一个Lambda表达式可以有零个或多个参数。
  • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a) 与(a)效果相同。
  • 所有参数需要包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
  • 空圆括号代表参数集为空。例如:() -> 42。
  • 当只有一个参数,且其类型可推导时,圆括号 () 可以省略。例如:a -> return a * a。
  • Lambda表达式的主体可包含零条或多条语句。
  • 如果Lambda表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致。例如:s -> System.out.println(s)
  • 如果Lambda表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空。

还有一个细节需要说明一下,看代码说话:

而如果加了return的话:

其实智能的IDE对于这种只有一条语句的完整写法也会提示我们写成expression的方式,如下:

好了,关于Lambda表达式的总结到这,已经对其了解得比较细了,下面还是回到这次要学习的主题上来。

Function接口:

下面开始编写代码来用一用这个接口,首先先利用Function这个接口来定义一个方法:

这方法定议了怎么使用它呢?看着挺奇怪的,甭急,下面先来看下如何使用它,当使用之后就能体会其意义了:

那为啥结果是2呢?分析一下:

程序理解上貌似不难,但是貌似还木有看出使用Function之后的好处,下面继续再多次调用下:

下面再来写一个返回String的Function,如下:

那举这几个形式的例子要说明啥呢?有点懵,其实重点是为了说明Lambda表达式传递的并非是值,而是一种形为,那如果不用Lambda表达式的方式,改用传统的方式那代码会变成什么样子呢?

那首先得定义三个方法如下:

然后再调用:

通过一对比,有木有看出来端倪,很明显光看compute这个方法,是无法知道具体的行为的,是加、减、乘、除,都不得而知,而具体的行为是在调用的时候才传递的,而传统的方式compute2是提前就定义好了行为之后,之后直接调用,这就是函数式编程跟面向对象编程的一个很大的区别,举这个例子就是用来体会这个区别的。

另外还有一个小细节提一下,就是由于目前咱们传的行为代码都只有一行,直接传木有啥问题~~但是如果这个行为代码量非常大,那可以将这个行为单独定义好,如下:

这样的话就不至于在行为比较复杂的时候显得代码过于零乱,当然具体如何写得根据实际情况。

高阶函数:

它的定义是:如果一个函数接收一个函数作为参数,或者返回一个函数作为返回值,那么该函数就叫做高阶函数。所以说像刚才我们定义的这个函数既可高阶函数:

这个在之后还会不断遇到的。

java8学习之Lambda表达式继续探讨&Function接口详解的更多相关文章

  1. java8学习之Lambda表达式初步与函数式接口

    对于Java8其实相比之前的的版本增加的内容是相当多的,其中有相当一大块的内容是关于Lambda表达式与Stream API,而这两部分是紧密结合而不能将其拆开来对待的,但是是可以单独使用的,所以从学 ...

  2. Java8学习笔记----Lambda表达式 (转)

    Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家       本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...

  3. JAVA8学习——深入浅出Lambda表达式(学习过程)

    JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...

  4. Java8学习(3)- Lambda 表达式

    猪脚:以下内容参考<Java 8 in Action> 本次学习内容: Lambda 基本模式 环绕执行模式 函数式接口,类型推断 方法引用 Lambda 复合 上一篇Java8学习(2) ...

  5. java8学习之Lambda表达式深入与流初步

    Lambda表达式深入: 在上一次[http://www.cnblogs.com/webor2006/p/8135873.html]中介绍Lambda表达式的作用时,其中说到这点: 如标红处所说,既然 ...

  6. Java8(1)之Lambda表达式初步与函数式接口

    Lambda表达式初步 介绍 什么是Lambda表达式? 在如 Lisp.Python.Ruby 编程语言中,Lambda 是一个用于表示匿名函数或闭包的运算符 为何需要lambda表达式? 在 Ja ...

  7. 每日学习心得:$.extend()方法和(function($){...})(jQuery)详解

    2014-02-09 前言: 节后头两天上班,主要是调整工作状态.项目也不是很紧,趁着周末把年前遇到了一些关于JS和JQuery的一些问题给总结一下.主要是介绍JQuery的extend方法和(fun ...

  8. Java8新特性-Lambda表达式是什么?

    目录 前言 匿名内部类 函数式接口 和 Lambda表达式语法 实现函数式接口并使用Lambda表达式: 所以Lambda表达式是什么? 实战应用 总结 前言 Java8新特性-Lambda表达式,好 ...

  9. Java8新特性 - Lambda表达式 - 基本知识

    A lambda expression is an unnamed block of code (or an unnamed function) with a list of formal param ...

随机推荐

  1. 20190925 - 使 macOS 的 rm 命令删除到回收站的不完美办法

    今天使用 macOS 时,使用 rm 删除了一个不重要文件,为保证以后不删除重要文件,找到一个让 rm 命令更安全的办法. 使用 MacPorts 安装 rmtrash 命令. sudo port i ...

  2. Elasticsearch全文检索引擎。什么是elasticsearch? 有什么特点? 怎么使用?

    什么是ElasticSearch? Elasticsearch是一个基于Lucene的搜索引擎.它提供了具有HTTPWeb界面和无架构JSON文档的分布式,多租户能力的全文搜索引擎.Elasticse ...

  3. 《精通并发与Netty》学习笔记(05 - Google Protobuf与Netty的结合)

    protobuf是由Google开发的一套对数据结构进行序列化的方法,可用做通信协议,数据存储格式,等等.其特点是不限语言.不限平台.扩展性强 Netty也提供了对Protobuf的天然支持,我们今天 ...

  4. Pytorch构建ResNet

    学了几天Pytorch,大致明白代码在干什么了,贴一下.. import torch from torch.utils.data import DataLoader from torchvision ...

  5. day23 xml模块、面向对象编程介绍

    今日内容: 1.xml模块 2.面向对象编程 一.xml模块 什么是xml? xml是一种可扩展的标记语言 xml语言的语法: <person name="jack"> ...

  6. Oooooooo AAAAE 【网络流最小点权覆盖】

    Description “Let the bass kick!O-oooooooooo AAAAE-A-A-I-A-U- JO-oooooooooooo AAE-O-A-A-U-U-A- E-eee- ...

  7. 20191204-使用nginx解决ajax测试调用接口跨域问题

    问题描述 之前要测试一个http的接口,在postman中测试成功,但使用ajax调用却跨域.于是通过使用ngin反向代理的方式来解决ajax调用跨域问题 测试页面的内容 <html> & ...

  8. 【Python】【demo实验6】【练习实例】【奖金发放计算(阶梯)】

    题目: 企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:20万到40万 ...

  9. wc、iconv命令

    一.wc:统计文件打印换行符,单词和字节数 语法:       wc [OPTION] ... [FILE] ...       wc [OPTION] ... --files0-from = F 描 ...

  10. 如何使用加多宝(jdb)在linux下调试Java程序

    毕业时写了一段时间的C,那时候调试使用gdb,后来转了java,当时就想java程序怎么调试,找了一下,果然,那就是jdk自带的jdb windows里是这样的 Linux下是这样的 一般我在linu ...