函数(功能)式接口
如果一个接口有且仅有一个抽象方法,那么这个接口就称为函数式接口(除Object中定义的方法外)
package com.startzj.inter;
//注解,用于验证是否满足函数式接口的要求
@FunctionalInterface
public interface Fly {
void fly();
}
Lambda表达式
作用:快速给函数式接口创建子类对象的
格式:(形式参数)->{代码块}
形式参数:多个参数用逗号分隔,无参数留空即可
代码块:具体要做的事情
使用前提(函数式接口)
- 有一个接口
- 接口中有且仅有一个抽象方法
表达式省略规则
- 参数类型可以省略,但是有多个的情况下,不能只省略一个
- 如果参数有且仅有一个,那么小括号也可以省略
- 如果代码块的语句只有一条,可以省略大括号和分号,甚至return
注意事项
- 必须有上下文环境,才能推导出Lambda表达式
- 局部变量的赋值:Runnable r = () ->System.out.println();
- 调用方法的参数:new Thread(() ->System.out.println()).start();
Lambda表达式与匿名内部类的区别
- 所需类型不同
- 匿名内部类:接口、抽象类、具体类
- Lambda:接口
- 使用限制不同
- 接口有且仅有一个抽象方法(函数式接口),可以用Lambda表达式也可以用匿名内部类
- 接口中有多个抽象方法,只能使用匿名内部类
- 实现原理不同
- 匿名内部类:编译之后,产生一个单独的字节码文件
- Lambda:无单独的字节码文件产生(动态生成)
package com.startzj.inter;
public class FlyTest {
public static void main(String[] args) {
Fly f = ()->{
System.out.println("飞机会飞");
};
f.fly();
//简写
//Lambda表达式作用:给函数式接口创建子类对象
Fly f = ()-> System.out.println("飞机会飞");
f.fly();
}
}
Supplier接口
生产者
有返回值,无参数
package java.util.function;
@FunctionalInterface
public interface Supplier<T> {
T get();
}
package com.startzj.consumer;
import java.util.Date;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
public class SupplierTest {
public static void main(String[] args) {
//生产型接口
//生产一个数字
Supplier<Integer> sup = ()->10;
System.out.println(sup.get());
Supplier<Integer> sup2 = SupplierTest::getAge;
System.out.println(sup2.get());
IntSupplier sup3 = SupplierTest::getAge;
System.out.println(sup3.getAsInt());
//生产当前日期
Supplier<Date> d = Date::new;
System.out.println(d.get());
}
public static int getAge(){
return 30;
}
}
Consumer接口
消费者
有参数,无返回值(void)
package java.util.function;
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
package com.startzj.consumer;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class ConsumerTest {
public static void main(String[] args) {
//如果通过对象(new一个对象)引用,则只消费一个参数
Consumer<String> cons1 = new ConsumerTest()::test;
cons1.accept("通过对象调用");
//如果通过类名引用,则消费2个参数,第一个参数是当前类的对象,第二个是String
BiConsumer<ConsumerTest,String> cons2 = ConsumerTest::test;
cons2.accept(new ConsumerTest(),"hello");
}
public void test(String s){
System.out.println(s);
}
}
Function接口
即是生产者,又是消费者
即有参数也有返回值
package java.util.function;
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
package com.startzj.consumer;
import java.util.function.Function;
public class FunctionTest {
public static void main(String[] args) {
//消费一个字符串,返回一个Integer类型的数据
Function<String,Integer> fun = s->Integer.valueOf(s);
System.out.println(fun.apply("30"));
//方法引用改造
Function<String,Integer> fun1 = Integer::parseInt;
System.out.println(fun1.apply("21"));
}
}
Predicate接口
断言式接口,返回boolean类型
判断对象是否符合某一个条件,返回Boolean类型
package java.util.function;
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
package com.startzj.consumer;
import java.util.Objects;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
public class PredicateTest {
public static void main(String[] args) {
//断言一个数字是否大于10
Predicate<Integer> pre = s->s>10;
System.out.println(pre.test(20));//true
//断言一个数字是否等于另一个数字
// BiPredicate<Integer,Integer> pre2 = (a, b)->a == b;
//方法引用
BiPredicate<Integer,Integer> pre2 = Objects::equals;
System.out.println(pre2.test(25, 30));//false
}
}