Lamdba-函数式编程《一》
Java中重要的函数接口
接口 | 参数 | 返回类型 | 事例 |
---|---|---|---|
Predicate | T | boolean | 是否通过测试 |
Consumer | T | void | 输出一个值 |
Function | T | R | 获取一个R类型的返回值 |
Supplier | None | T | 工厂方法 |
UnaryOperator | T | T | 逻辑非(!) |
BinaryOperator | (T,T) | T | 求两个数的和或者乘积 |
Lambda表达式辨别
表达式变种写法:
1. Runnable noArguments = () ->System.out.println("Hello World");
2.ActionListener oneArgument = event -> System.out.println("Hello World");
3. Runnable multiStatement = () ->{
System.out.println("Hello");
System.out.println("World");
}
4.BinaryOpterator<Long> add = (x,y) -> x+y;
5.BinaryOpterator<Long> add = (Long x,Long y) -> x+y;
()代表无参数。{} 可以用于代码块 4/5的写法由于4的写法可以被上下文环境解析编译器推断出的,给予默认值。
Lambda表达式是引用值,不是变量
尝试在main方法中编写如下代码你会发现,编译器会有何提示?强制运行之后会提示什么?
Integer initNum =0;
// 此处如果对initNum做了值操作,那么编译器首先会报错,
//提示:变量在lambda中使用 必须是final的或者既成事实的final
Runnable runnable = () -> System.out.println(initNum++);
runnable.run();
由上述例子可以得出:lambda引用的是值,不是变量,虽然java8 没有强制要求写上final关键字,但是实际上相当于编译过程程序自动添加了。没强制添加,只是增加了代码的可读性吧。这也就是为什么Lambda表达式也被称之为闭包的原因。
Lambda类型推断
早在Java7的时候 类型推断就已经存在,如:
1和2的效果完全一致,map1中采用菱形<>操作符进行类型推断
Map<String, Integer> map1 = new HashMap<>();
Map<String, Integer> map2 = new HashMap<String, Integer>();
下面做一个事例:
Predicate<Integer> result = x -> x > 5;
System.out.println(result.test(7));
Predicate接口源码,接受一个对象,返回一个布尔值
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
接口示意图:
T -Predicate-boolean
Predicate只有一个范型类型参数,Lambda表达式实现了该接口,所以单一参数被推断为Integer.