介绍
Lamda表达式,读作λ表达式,是函数式编程的概念,java8引入了函数式编程,可以简化一些代码开发工作,例如,在编写内部类的时候只有简单的代码可以使用函数式编程来。
这里Caller类调用caller方法依赖到IFunction接口的show方法
所以新建了一个内部类来实现。
public class LamdaTest {
public static void main(String[] args) {
Caller caller = new Caller();
caller.call(new IFunction() {
@Override
public void show() {
System.out.println("calling IFunction's show method");
}
});
}
}
class Caller {
public void call(IFunction iFunction) {
iFunction.show();
}
}
interface IFunction {
void show();
}
用函数式编程的方式来实现。简洁了很多。
public class LamdaTest {
public static void main(String[] args) {
Caller caller = new Caller();
caller.call(() -> System.out.println("calling IFunction's show method"));
}
}
interface IFunction {
void show();
}
class Caller {
public void call(IFunction iFunction) {
iFunction.show();
}
}
使用方式
首先来说明下java8中接口的新特性
- 接口中可以有静态方法
接口里面的方法,可以是静态的,调用方式跟类的静态方法一样 - 方法可以有默认实现
接口可以提供默认方法,里面可以有具体的实现,在方法声明前面添加defaul来修饰,使得我们在扩展某些接口的时候,不需要把系统原有的实现类都扩展一遍。
函数式编程可以以代码块的方式来实现某个只有一个抽象方法的接口,而不需要显式声明或者以内部类的方式来实现,而这些接口一般也称为函数式接口(functional interface),通过在类前面使用@FunctionalInterface来表明该接口可以提供为函数式编程,这个注解没有特别要求,只是为了规范设计。
Lamda语法
语法结构为:(参数…) 箭头 代码块
简化规则:
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
(Object ...) -> {...}
例子:
没有参数, 没有返回值的
常用语法
() -> {
System.out.println("hello lamda");
}
简明语法
() -> System.out.println("hello lamda");
一个参数, 没有返回值的
常用语法
(String a) -> {
System.out.println(a);
}
简明语法
a -> System.out.println(a);
两个(多个)参数, 没有返回值的
常用语法
(a, b) -> {
System.out.println(a + b);
}
简明语法
(a, b) -> System.out.println(a + b);
两个(多个)参数, 有返回值
常用语法
(a, b) -> {
return a + b;
}
简明语法
(a, b) -> a + b;
引用外部方法
有时候我们可以把某个现有方法当做接口里面的实现,实际就是把某个函数当做接口函数的实现了。
实现方式:
Object::instanceMethod
Class::staticMethod
Class::instanceMethod
例子
public class LamdaTest {
public static void main(String[] args) {
//使用lamda表达式来直接实现
IFunction iFunction = str -> System.out.println(str);
iFunction.show("hello lamda statement");
//使用方法引用来实现,这里就是把print函数当做IFunctin的show的实现
IFunction iFunction2 = LamdaTest::print;
iFunction.show("hello lamda method");
}
public static void print(String str) {
System.out.println(str);
}
}
interface IFunction {
void show(String str);
}
引用构造器
跟方法引用一样,可以通过构造器引用给一些返回特点对象的函数式接口。
方式
类名::new
这里的new实际是调用类的构造器,所以接口的中参数要和类的构造器的参数一致
例子
public class LamdaTest2 {
public static void main(String[] args) {
IFunction2 iFunction2 = Person::new;
Person person = iFunction2.getPerson("new name");
System.out.println(person.getName());
}
}
interface IFunction2 {
Person getPerson(String name);
}
class Person {
private String name = "default name";
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
java8常用函数式接口
- Function
- Consumer
- Perdicate
- Supplier
- Runnable
例子测试
package javat.lamda;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.function.*;
public class FunctionInterfaceTest {
public static void main(String[] args) {
//获取根据第二个泛型的参数,返回第一个泛型的结果
Function<Integer, String> function = (Integer i) -> "str of param is " + String.valueOf(21);
System.out.println(function.apply(1000));
System.out.println("===================================");
//传进来一个参数,供消费
Consumer consumer = System.out::println;
consumer.accept("hello world");
System.out.println("===================================");
//判断参数是否符合某个条件
Predicate<Integer> predicate = o -> o == 3 ? true : false;
for (int i = 0; i < 5; i++) {
if (predicate.test(i)) {
System.out.println("bingo bingo");
} else {
System.out.println("wrong answer which is " + i);
}
}
System.out.println("===================================");
//提供某个值
Random random = new Random(10);
Supplier supplier = () -> {
return random.nextInt(100);
};
int count = 0;
while (count++ < 5) {
System.out.println(supplier.get());
}
System.out.println("===================================");
//提供一个运行代码块
Runnable runnable = () -> {
System.out.println(1);
System.out.println(2);
System.out.println(3);
};
runnable.run();
System.out.println("===================================");
}
}