
前言
项目中偶有使用Java8,了解一些基本的用法,但是没有来得及系统的学习,所以一些概念比较模糊,没有理解透彻,最近把一些教程和书籍细细地看了一下,觉得豁然开朗了许多,之前有些不理解的概念也理清了,在这里总结了一下。

函数式编程(面向声明、而非过程)
在Java8中,会看到很多类似下面风格的代码:使用Labmda表达式。这种写法就是一种声明式的写法:告诉计算机要做什么,而不是怎么做。
//我们通过函数声明式的过滤出我们想要的结果。而不是在写个for循环做条件判断,然后筛选结果(过程式)
Arrays.asList(1, 3, 4, 5, 10).stream().filter(v -> v > 5).collect(Collectors.toList());
复制代码
函数接口
只有一个抽象方法,可有多个默认实现的接口。定义一个函数接口,如下:
@FunctionalInterface //添加这个注解后,编译器会检查当前的接口是否符合函数接口规范 public interface Formula { double calucalte(int value); default int sum(int v1, int v2) { //默认实现方法,当实现接口时可以不实现 return v1 + v2; } default double maxValue(Double... values) {//计算所给参数的最大值 return Arrays.stream(values).max(Double::compareTo).orElse(0.0); } } 复制代码
接口的默认方法
- 为什么要有这个特性
之前的接口好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类。对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。我觉得这里就解释的很好: 链接
Lambda表达式
- 为什么使用Lambda表达式?
使得对接口的实现更加简单明了,代码更加清晰,对上面的代码进行测试:
//Java8以前的做法:实例化接口 Formula formu = new Formula() { @Override public double calucalte(int value) { return sum(value, 10);//可以直接调用接口中的默认实现方法 } }; System.out.println(formu.calucalte(10)); //使用Lambda表达式的做法:本质上还是接口实现。 Formula formula = a -> a + 1;//语法:参数列表->Lambda主体(相当于函数接口的实现),编译器会对参数类型进行判断 System.out.println(formula.maxValue()); 复制代码
函数的传递
在Java的核心类库中,经常可以看到在方法中传递函数,下图是 Collections
类中的一个方法:

//Java8之前:
List<Integer> values = Arrays.asList(9, 1, 2, 4, 5);
Collections.sort(values, new Comparator<Integer>() {//往方法中传递函数的代码,该方法需要用到函数的执行结果
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
//Java8:一行代码解决
Collections.sort(values, Integer::compareTo);//方法引用:复用已存在的方法
复制代码
JDK提供函数接口
JDK中提供了很多实用的函数接口,大概列出了一些,具体可看下API文档,在使用过程看下源码可以理解的更透彻。 Stream API
中很多方法使用了这些函数接口。
函数接口 | 抽象方法 | 说明 |
---|---|---|
Predicate 断定型 | boolean test(T t); | 确定给定类型参数是否满足某种约束 |
Consumer 消费型 | void accept(T t); | 对给定类型参数进行操作 |
Supplier 供给型 | T get(); | 返回结果 |
R apply(T t) 函数性 | R apply(T t); | 对T类型进行操作、返回R类型结果 |
- 看下这些接口在源码当中的使用:
//Strem类中的filter方法:通过某种规则进行过滤。
Stream<T> filter(Predicate<? super T> predicate);
//使用时用Lambda表达式实现接口
List list = Stream.of(1, 3, 4, 5, 10).filter(v -> v > 5).collect(Collectors.toList());
复制代码
流(Stream)
构建流
如何从值序列、数组、文件来构建流?可用 Stream.of()
、 Arrays.stream()
方法
//由值构建 String s = "sunnyDay"; List list = Stream.of(s).collect(Collectors.toList());//使用Stream.of()构建流 //由数组构建 int[] numbers = {2, 0, 2, 0}; int sum = Arrays.stream(numbers).sum(); 复制代码
收集器
对 stream
中的元素作汇总:生成List、Map
原文
https://juejin.im/post/5e7e1aaf51882573c04cbdcb
本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 浅谈Java8