1. Lambda表达式的使用
Lambda是JDK1.8
推出的重要新特性,使用函数式编程。
函数式编程和面向对象编程可以理解为两大开发阵营。面向对象最大的局限在于:结构必须完整。比如:在写一个main方法,必须创建一个包,写一个类,定义一个main方法,然后在写输出语句。
举例:传统面向对象开发
public interface IMessage {
void print();
}
class TestLambda{
public static void main(String[] args) {
IMessage m = new IMessage(){ //匿名内部类
@Override
public void print() { //必须编写完整语法
System.out.println("IMessage实现类");
}
} ;
m.print();
}
}
对于上述,采用了更简化的方法,函数式编程。
举例:采用函数式编程
public interface IMessage {
void print();
}
class TestLambda{
public static void main(String[] args) {
//函数式编程的使用,目的是输出一句话
IMessage m = () -> System.out.println("IMessage实现类");
m.print();
}
}
函数式编程的前提:接口中必须只有一个方法,如果有两个方法,则无法使用。如果现在有有一个接口就是为了函数式编程而生的,那么在定义的时候只能够定义一个方法。
函数式编程使用总结:
- 函数式编程对应到数学中:y = f(x), 其中f -> function;
- 接口中只能定义一个抽象方法;
- 为了防止函数接口中定义多于一个抽象方法,在接口定义时使用@FunctionalInterface;
- 使用lambda表示语法:
(参数) -> 单行语句;
(参数) -> { } ; { }中是多行语句;
举例:使用@FunctionalInterface
注解
//是一个函数式编程接口,只允许有一个方法
@FunctionalInterface
public interface IMessage {
void print();
}
class TestLambda{
public static void main(String[] args) {
IMessage m = ()->{
System.out.println("IMessage实现类");
System.out.println("IMessage实现类");
};
m.print();
}
}
举例:函数式编程计算
@FunctionalInterface
interface IAdd{
int add(int a, int b);
}
public class TestLambda {
public static void main(String[] args) {
//如果return中只有一个语句,则省略return
IAdd iAdd = (a,b)-> a+b;
System.out.println(iAdd.add(2,3));
}
}
lambda使用注意事项:
- lambda的方法体:
(参数名列表) -> {
code1;
code2;
[return];
}
- 如果方法体中只有一条语句,并作为返回值,则省略return;
- 如果方法体中只有一条语句,可以省
{
}`; - 使用注意举例:
public class TestLambda {
public static void main(String[] args) {
//1. int a = 0; 错误,参数列表中的变量名称不能和外部代码变量重名
int c = 2;
IAdd iAdd = (a,b)-> {
//2. c = 0; 错误
//如果方法体中访问外部变量,隐式被final修饰,不能被修改
return a+b;
};
System.out.println(iAdd.add(2,3));
}
}
2. 内建函数接口
lambda的核心在于:函数式接口。而函数式接口的核心:只有一个方法。
java.util.function将函数式编程分为以下四种接口:
- 功能型函数式接口:public interface Function<T, R> ---- R apply(T t);
- 供给型函数接口:public interface Supplier ---- T get();
- 消费型函数式接口:public interface Consumer ---- void accept(T t);
- 断言型接口:public interface Predicate ---- boolean test(T t);
它们是JDK内部提供的函数。
2.1 功能型接口
功能型是指你输入一个数据,而后将数据处理后进行输出。
举例:使用该接口
public class TestLambda {
public static void main(String[] args) {
/*
Function<Integer,String> function = (t)->{
return String.valueOf(t);
};*/
Function<Integer,String> function = String::valueOf;
System.out.println(function.apply(5)); //5
}
}
2.2 供给型接口
目的是获取一个结果。
举例:使用该接口
public class TestLambda {
public static void main(String[] args) {
String str = "hello";
/*
Supplier<String> supplier = ()->{
return str.toUpperCase();
};*/
Supplier<String> supplier = str::toUpperCase;
System.out.println(supplier.get());
}
}
2.3 消费型接口
在给定的参数上执行一定的操作。
举例:使用该接口
public class TestLambda {
public static void main(String[] args) {
/*
Consumer<String> consumer = (t)->{
System.out.println(t);
};*/
Consumer<String> consumer = System.out::println;
consumer.accept("hello"); //hello
Consumer<Integer[]> consumer1 = (arrays)->{
for (Integer array:arrays) {
System.out.print(array+",");
}
};
consumer1.accept(new Integer[]{1,2,3});
}
}
2.4 断言型接口
主要用于判断。
举例:使用该接口
public class TestLambda {
public static void main(String[] args) {
String str = "JavaScript";
Predicate<String> predicate = str::startsWith;
System.out.println(predicate.test(str)); //true
}
}