当前位置: 移动技术网 > IT编程>开发语言>Java > Java 8 实战

Java 8 实战

2019年03月28日  | 移动技术网IT编程  | 我要评论

java8 函数式接口,方法传递与lambda

java8新特性

 

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

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

### java8函数式接口,方法传递与lambda
- @functionalinterface标注一个函数式接口
- 常用函数式接口
1. predicate : t -> boolean
1. 用于判断
1. test | and | or | negate
1. function : t -> r
1. apply | andthen | compose
1. consumer : t -> void
1. 消费者,用于执行操作
1. accept | andthen
1. supplier : () -> t
1. 供应商
1. get
1. compare
1. 用于比较
1. compare | comparing | reversed | thencomparing
- lambda
1. lambda是对函数式接口的简洁的实现方式
1. lambda将java这种强类型,面向对象语言变得灵活,简洁
1. 可以将lambda赋值给一个函数式接口句柄
1. 支持参数类型推断,可以省略参数类型
1. 将lambda运用于重载方法上的时候,重载方法的函数式接口的参数或者返回值不能相同,否则lambda类型检查报错
1. lambda实体内部可以使用局部变量,但是这个局部变量必须是final或者实际上是final的
1. (t t) -> u : 这个lambda描述符可以用方法已有的方法传递代替
- 神奇的例子
1. 将一个apple的list按重量排序
1. 传统做法是自己写一个冒泡算法按重量排序
1. 只对苹果list有效
1. 只对苹果重量有效
1. 需要自己实现算法
1. 通过范型使得所有list有效
1. 通过bipredicate函数接口和lambda解决重量限制
1. 再将排序算法写入list,使得算法公用
1. 通过以上我们可以对任何list按照自定义规则排序,近乎完美,但是我们仍不满足,是否能将lambda也省略?也就是将排序规则省略,只通过给出的属性按照属性自己的比较规则排序。这样做的前提是给出的属性必须实现统一接口comparable
1. lambda嵌套:当一个函数式接口的几个参数是同一个类,并且实现方法里都是调用的这个类的同一个方法时,可以嵌套使用function函数接口作为参数来构建这个函数式接口,这样做就可以使得实现方法也可以传递方法,并且可以减少参数,当然,不同类的参数也能嵌套
^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^ stream ^^^^^^^^^^^^^^^^^^
### stream 特性
1. 流操作分为中间操作和终端操作,中间操作只有在终端操作被触发时才有效,这个理念类似于构建器模式
1. 这种流水线理念的好处:可以通过循环合并,短路等技巧将中间操作合并处理,提高计算性能。
1. 流只能被消费一次

### 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提供的条件筛选
1. distinct() : 去重
1. limit(long maxsize) : 截断
1. skip(long n) : 跳过
- 映射
1. map(function f) :获取流的特定规则的映射
1. flatmap(function f) : 扁平化流
1. maptoint(tointfunction tf) :转换为数值流
- 排序
1. sorted(comparator c) :通过指定比较器排序

### 终端操作:返回一个非流
- 查找与匹配
1. anymatch(predicate p)
1. allmatch(predicate p)
1. nonemach(predicate p)
1. findfirst() : 查找第一个
1. findany() : 查找任意一个,虽然findfirst也能实现,但是在并行流中建议使用findany
- 归约
1. reduce(t identity, binaryoperator<t> accumulator) :
1. 对所有元素进行计算得出一个结果,比如获取最大最小值
1. 与map合用便是著名的map-reduce模式
1. 三个参数的reduce方法中间的参数相当于map的功能
1. collect(collector c) : 返回一个集合, 参照collectors
1. 和reduce的区别?
- 其他
1. foreach(consumer c) : 内部循环
1. count()

^^^^^^^^^^^^^^^^^^^^^^^^^^^

^^^^^^^^^^^^^收集器^^^^^^^^^^^^^^
### collectors
- 分组
1. groupingby(function f)
1. groupingby(function f, collector c) :多极分组/分组后归约
- 归约
1. collectors.reducing(binaryoperator bo) : 所有归约都是reducing的特殊化例子
1. tolist()
1. counting()
1. maxby/minby(comparator c)
1. averagingdouble/summingdouble(todoublefunction f)
1. joining() : 连接字符串


### google guava collections
^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网