Java8新特性Stream学习(一)初露锋芒
初露锋芒
image距离Java8发布已经过了四年,但是很多朋友依旧使用着Java7,甚至Java6,也不是说不行,但是对于新的东西我们还是要敢于去尝试,毕竟可以带来一定效率提升,为了帮助更多朋友过渡到Java8,所以把自己学习的一些总结写出来,希望新手可以少走很多弯路。使用JDK8如果没有使用它的新特性,和没有使用JDK8是同一回事。
初识Lambda
讲到Stream咱们必须了解一下Lambda,因为Stream里面API大部分都是基于Lambda实现的,可以说Stream将Lambda使用的淋漓尽致,说个题外话,在响应式编程并不提倡使用java提供Stream来完成流式操作,而是推荐使用实现了响应式规范的框架Reactor 3,当然在Spring5.0之后使用WebFlux也可以很好的体验响应式编程,如果后期有时间本人会更新相应的文章。不过咱们也不需要担心Webflux学起来困难,因为把Stream学好可以很快上手。
什么是Lambda
第一个Lambda
BinaryOperator<Integer> sum = (x, y) -> x + y;
提到Lambda相信很多第一会说,带有->的就是Lambda,的确Lambda表达式其中一个明显的特征就是使用->来表示。让我们回到第一个Lambda,从代码中可以看到我们定义了一个x和一个y,然后使用->来连接对应操作。从这里可以看出Lambda是一组表达式,仅仅是一组表达式么,那肯定不是了,让我们看下面这个例子,看不懂的业没有关系,因为我们后面会讲到的。
students.stream().filter(student -> {
System.out.println(student.getName());
return student.isMan();
});
在上面这段代码中,我们输出了学生的姓名,然后还返回了一个Boolean值,这时我们又可以得知一点Lambda还可以是方法(是不是感觉和匿名方法很像,这里就是匿名方法,不过比之前的匿名方法看起来更简洁,后面会详细讲解的)。当然不仅如此,在lambda中还可以使用局部变量,<b>不过请悉知lambda中并不是引用的变量,而是值,在lambda中的className是使用final修饰的,只不过java帮我们隐藏了。</b>
String className = "高三五班";
students.stream().peek(student -> student.setClassName(className));
lambda重要的接口
方法名 | 参数 | 返回类型 | 示例 |
---|---|---|---|
Predicate<T> | T | boolean | 这个学生是男生吗 |
Consumer<T> | T | void | 输出一个值 |
Function<T,R> | T | R | 获得Artist 对象的名字 |
Supplier<T> | None | T | 工厂方法 |
UnaryOperator<T> | T | T | 逻辑非( !) |
BinaryOperator<T> | (T, T) | T | 数值计算 |
lambda接口创建
看了官方的介绍,对于函数式接口定义:一个接口中只能包含一个抽象方法,static和default修饰的不计(在java8之后支持在接口中有默认实现,只需要用default修饰即可),在接口中添加@FunctionalInterface即可,@FunctionalInterface也可以不用加,不过加上这个注解我们便能一目了然它是一个函数式的接口。下面我们看一个简单的Demo。
一、函数式接口的定义
@FunctionalInterface
public interface Numerical {
/**
* 默认方法
* @param message
*/
void hello(String message);
/**
* 数值计算
* @param x
* @param y
* @param m
* @return
*/
static<T> T calc(BinaryOperator<T> m, T x, T y){
return m.apply(x, y);
}
}
二、使用
public class Demo {
public static void main(String[] args) {
// 自己实现一个函数式接口
Numerical numerical = (message -> System.out.println("Hello:" + message));
numerical.hello("Tom");
// 利用Lambda实现一个灵活的数值计算器
// 求和
BinaryOperator<Integer> sum = (x, y) -> x + y;
System.out.println("sum:" + sum.apply(5, 10));
// 求积
BinaryOperator<Integer> product = (x, y) -> x * y;
System.out.println("product:" + product.apply(5, 10));
// 复杂运算
BinaryOperator<Integer> complex = (x, y) -> ((x - 1) * (y * y)) - 5;
System.out.println("complex:" + complex.apply(5, 10));
}
}
================================
结果:
Hello:Tom
sum:15
product:50
complex:395
=================================
总结
- Lambda是一个匿名方法,将行为像数据一样进行传递。
- 函数式接口指的是仅有一个抽象方法的接口,用来表示Lambda的类型。
-
看完这个简单的Demo是对lambda有了一定的了解,如果还是不懂没关系,咱们还有详细讲解的。
这是一个系列的文章,接下来会陆续更新。 -
由于本人的能力有限,有些地方可能讲解的并不是很到位,如果有写错的地方欢迎大家指正。