Java8 函数式接口,方法传递与Lambda

Java8新特性

  • 方法作为参数传递给方法,方法成为一等公民
  • Lambda,匿名函数
  • Stream API :
    1. 将一系列相关操作用流水线的思想分配到CPU的不同内核上并行操作,而不需要费劲的使用Thread实现
    2. 每个流就是一系列数据项,每个流能独立的完成已有的数据向,虽然流B的数据项是由流A生产,但是不需要等待流A完成所有数据项的生产,流A会把已经完成的数据向传给流B,好让流B同时工作
    3. 提倡数据分块而不是协调访问,就是说几个线程最好不要同时更新共享变量,尽量不用synchronized
    4. Stream的并行特性必须保证传递给流的方法没有互动(比如有可变的共享变量)
  • 函数式编程思想
  • 默认方法,使接口更方便
  • Opthinal避免空指针异常

行为参数化 : 使代码从死板,罗嗦走向灵活,简洁

  • 通过颜色,重量等条件筛选苹果的例子
  • 方法1:条件作为参数传递给方法,死板,罗嗦
  • 方法2:通过Filter接口与不同的实现类,将实现类作为参数,灵活但是罗嗦
  • 方法3:通过匿名类来代替实现类,灵活但还是比较罗嗦
  • 方法4:通过方法传递代替匿名类,灵活但还是有点罗嗦,但是如果方法已经存在,那这种方式就比Lambda简洁
  • 方法5:通过Lambda表达式与函数式接口(只有一个抽象方法)代替方法传递,灵活并且简洁
  • 扩展6:使用范型替代苹果,可以筛选基础类型以外的任何类型,接近完美

Java8函数式接口,方法传递与Lambda

  • @FunctionalInterface标注一个函数式接口
  • 常用函数式接口
    1. Predicate : T -> boolean

      1. 用于判断
      2. test | and | or | negate
    2. Function : T -> R
      1. apply | andThen | compose
    3. Consumer : T -> void
      1. 消费者,用于执行操作
      2. accept | andThen
    4. Supplier : () -> T
      1. 供应商
      2. get
    5. Compare
      1. 用于比较
      2. compare | comparing | reversed | thenComparing
  • Lambda
    1. Lambda是对函数式接口的简洁的实现方式
    2. Lambda将java这种强类型,面向对象语言变得灵活,简洁
    3. 可以将Lambda赋值给一个函数式接口句柄
    4. 支持参数类型推断,可以省略参数类型
    5. 将Lambda运用于重载方法上的时候,重载方法的函数式接口的参数或者返回值不能相同,否则Lambda类型检查报错
    6. Lambda实体内部可以使用局部变量,但是这个局部变量必须是final或者实际上是final的
    7. (T t) -> U : 这个Lambda描述符可以用方法已有的方法传递代替
  • 神奇的例子
    1. 将一个apple的List按重量排序
    2. 传统做法是自己写一个冒泡算法按重量排序
      1. 只对苹果List有效
      2. 只对苹果重量有效
      3. 需要自己实现算法
    3. 通过范型使得所有List有效
    4. 通过BiPredicate函数接口和Lambda解决重量限制
    5. 再将排序算法写入list,使得算法公用
    6. 通过以上我们可以对任何List按照自定义规则排序,近乎完美,但是我们仍不满足,是否能将Lambda也省略?也就是将排序规则省略,只通过给出的属性按照属性自己的比较规则排序。这样做的前提是给出的属性必须实现统一接口Comparable
    7. Lambda嵌套:当一个函数式接口的几个参数是同一个类,并且实现方法里都是调用的这个类的同一个方法时,可以嵌套使用Function函数接口作为参数来构建这个函数式接口,这样做就可以使得实现方法也可以传递方法,并且可以减少参数,当然,不同类的参数也能嵌套

Stream

Stream 特性

  1. 流操作分为中间操作和终端操作,中间操作只有在终端操作被触发时才有效,这个理念类似于构建器模式
  2. 这种流水线理念的好处:可以通过循环合并,短路等技巧将中间操作合并处理,提高计算性能。
  3. 流只能被消费一次

Stream类

  • ReferencePipeline

    1. mapToInt(ToIntFunction tf) :转换为数值流
  • 数值流IntStream/DoubleStream/LongStream
    1. boxed() : 转换为对象流

创建Stream

  • Stream.of :手动添加值
  • Arrays.stream(strs) :通过数组
  • Files.lines(Path path) : 通过文件
  • String.iterate(T seed, UnaryOperator f) : 迭代,无限流无法排序或者归约
  • Stream.generate(Math::random) : 生成,无限流

中间操作,通过一个流返回另一个流,组成流水线

  • 筛选与切片

    1. filter(Predicate p) : 按lambda提供的条件筛选
    2. distinct() : 去重
    3. limit(long maxSize) : 截断
    4. skip(long n) : 跳过
  • 映射
    1. map(Function f) :获取流的特定规则的映射
    2. flatMap(Function f) : 扁平化流
    3. mapToInt(ToIntFunction tf) :转换为数值流
  • 排序
    1. sorted(Comparator c) :通过指定比较器排序

终端操作:返回一个非流

  • 查找与匹配

    1. anyMatch(Predicate p)
    2. allMatch(Predicate p)
    3. noneMach(Predicate p)
    4. findFirst() : 查找第一个
    5. findAny() : 查找任意一个,虽然findFirst也能实现,但是在并行流中建议使用findAny
  • 归约
    1. reduce(T identity, BinaryOperator accumulator) :

      1. 对所有元素进行计算得出一个结果,比如获取最大最小值
      2. 与map合用便是著名的map-reduce模式
      3. 三个参数的reduce方法中间的参数相当于map的功能
    2. collect(Collector c) : 返回一个集合, 参照Collectors
      1. 和reduce的区别?
  • 其他
    1. forEach(Consumer c) : 内部循环
    2. count()

收集器

Collectors

  • 分组

    1. groupingBy(Function f)
    2. groupingBy(Function f, Collector c) :多极分组/分组后归约
  • 归约

    1. Collectors.reducing(BinaryOperator bo) : 所有归约都是reducing的特殊化例子
    2. toList()
    3. counting()
    4. maxBy/minBy(Comparator c)
    5. averagingDouble/summingDouble(ToDoubleFunction f)
    6. joining() : 连接字符串

google guava collections

思考

  • 接口拥有了默认方法后,抽象类的意义何在
  • Lambda实体内部可以使用局部变量,但是这个局部变量必须是final或者实际上是final的?
  • List.sort()方法的源码分析
  • 流的有状态和无状态
  • reduce和collect的区别

Java 8 实战的更多相关文章

  1. selenium2 Webdriver + Java 自动化测试实战和完全教程

    selenium2 Webdriver + Java 自动化测试实战和完全教程一.快速开始 博客分类: Selenium-webdriverselenium webdriver 学习selenium ...

  2. Java日志实战及解析

    Java日志实战及解析 日志是程序员必须掌握的基础技能之一,如果您写的软件没有日志,可以说你没有成为一个真正意义上的程序员. 为什么要记日志? •       监控代码 •       变量变化情况, ...

  3. Java编程实战宝典PDF (中文版带书签)

    Java编程实战宝典PDF 目录 第1篇 Java基础知识入门第1章 Java的开发运行环境( 教学视频:57分钟)1.1 Java运行原理与Java虚拟机1.1.1 Java运行原理简述1.1.2 ...

  4. 《Java 8实战》读书笔记系列——第三部分:高效Java 8编程(四):使用新的日期时间API

    https://www.lilu.org.cn/https://www.lilu.org.cn/ 第十二章:新的日期时间API 在Java 8之前,我们常用的日期时间API是java.util.Dat ...

  5. 《selenium2 Java 自动化测试实战(第二版)》 更新2016.5.3

    java 版来了!! 本文档在<selenium2 Python 自动化测试实战>的基础上,将代码与实例替换为java ,当然,部分章节有变更.这主要更语言本身的特点有关.集合和java下 ...

  6. 【Java】实战Java虚拟机之五“开启JIT编译”

    今天开始实战Java虚拟机之五“开启JIT编译” 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实战Ja ...

  7. Java反射实战

    一.背景 最近的项目中需要使用到Java 反射的知识,以前不怎么了解,也基本没怎么用过,抽出一片时间,来具体学习和实战下Java的反射!拿来和大家分享以及记录方便以后学习! 二.反射相关概念解析 1. ...

  8. Java BTrace实战(1)--BTrace的入门和使用

    前言: 对线上的java服务, 往往采用日志进行问题处理和分析. 倘若日志缺乏相关的信息时, 那又该如何处理? 远程调试会影响服务的正常工作, 修改代码重新部署的方案其实时性和灵活性难以保证(线上服务 ...

  9. Java 10 实战第 1 篇:局部变量类型推断

    现在 Java 9 被遗弃了直接升级到了 Java 10,之前也发过 Java 10 新特性的文章,现在是开始实战 Java 10 的时候了. 今天要实战的是 Java 10 中最重要的特性:局部变量 ...

  10. 读书笔记,《Java 8实战》,第三章,Lambda表达式

    第一节,Lambda管中窥豹    可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式,它没有名称,但它有参数列表.函数主题和返回值.    本节介绍了Lambda表达式的语法,它包括 ...

随机推荐

  1. 替代iframe

    1.jq中 通过JQuery的load()方法动态加载页面. $( "#result" ).load( "app/test.html" ); 2.vue.rea ...

  2. Azulão--青鸟--IPA--巴西葡萄牙语

    这是巴西很有名的民谣.

  3. Android : apk签名的多种方法以及key的配置

    方法一:使用Android SDK中的签名工具给apk签名: (1)Android源码的 build/target/product/security/ 目录下有 media.pk8.media.x50 ...

  4. 2.17 C++类与const关键字

    参考: http://www.weixueyuan.net/view/6348.html 总结: const成员变量的初始化只有唯一的一条途径:参数初始化表. const成员函数可以使用类中的所有成员 ...

  5. JavaScript示例

    <!DOCTYPE html> <html> <head> <title>单击按钮事件示例</title> <script langu ...

  6. python中的if判断语句

    判断(if)语句 目标 开发中的应用场景 if 语句体验 if 语句进阶 综合应用 01. 开发中的应用场景 生活中的判断几乎是无所不在的,我们每天都在做各种各样的选择,如果这样?如果那样?……  ...

  7. 漫步Java------接口

    接口 一.定义 具有相同行为(方法),但是不相关的类 二.特点 只是提供方法,不定义方法的具体实现. 一个类只能继承一个父类,但是接口却可以继承多个接口. 接口是一个引用类型的变量 接口没有构造方法, ...

  8. ksort 函数

    foreach ($modules AS $key => $value){ ksort($modules[$key]);}ksort($modules); strpos(','.$_SESSIO ...

  9. mysql三范式

    第一范式:有主键,具有原子性,字段不可分割. 第二范式:完全依赖,没有部分依赖. 第三范式:没有传递依赖. 总结:数据库设计尽量遵循三范式,但是还是根据实际情况进行取舍,有时候会拿冗余还速度,最总用的 ...

  10. TEST mathjax

    这里是第一个公式 $ F = ma^2 $ \[ \text{Reinforcement Learning} \doteq \pi_* \\ \quad \updownarrow \\ \pi_* \ ...