网站首页 > 基础教程 正文
简介
lambda 表达式的类型,也被称为“目标类型(target type)”,lambda 表达式的目标类型必须是“函数式接口(functional interface)”。函数式接口代表只包含一个抽象方法的接口。函数式接口可以包含多个默认方法、类方法,但是只能声明一个抽象方法。
从这里可以看到,Java 8 对接口增加了 static 以及 default 关键字,就可以说的通了。为了让 @FunctionalInterface(函数式接口)使用起来更加方便。
Java8 专门为函数式接口提供了 @FunctionalInterface 注解,该注解通常放在接口定义前面,该注解对程序功能没有任何作用,他用于告诉编译器执行更加严格的检查——检查该接口必须是函数式接口,否则编译器就会报错。
代码示例
lambda 表达式的限制
由于 lambda 表达式的结果就是被当成对象,因此程序中完全可以使用 lambda 表达式进行赋值。
// Runnable 接口中只包含一个无参的方法
// lambda 表达式代表的匿名方法实现了 Runnable 接口中的唯一的、无参方法
// 下面的语句创建了一个 Runnable 对象
Runnable r = () -> {
for( int i=0; i<100; i++ ){
System.out.println();
}
}
lambda 表达式实现的是匿名方法——因此它只能实现特定函数式接口中的唯一方法。因此可以看到 lambda 表达式有如下两个限制。
- lambda 表达式的目标类型必须是明确的函数式接口。
- lambda 表达式只能为函数式接口创建对象。lambda 表达式只能实现一个方法,因此它只能为只有一个抽象方法的接口(函数式接口)创建对象。
错误的代码
// 这段代码是错误的
// 会报:不兼容的类型: object 不是函数接口
Object obj = () -> {
for( int i=0; i<100; i++ ){
System.out.println();
}
}
Java 8 中的4类内建函数式接口
- XxxFunction,功能型接口。 语法:public interface Function<T,R>{public R apply(T t);}。该接口通常用于对指定数据进行转换处理。 apply() 抽象方法,对参数进行处理、转换。然后返回一个新的值。
- XxxConsumer,消费型接口。语法:public interface Consumer<T>{public void accept(T t);}。该方法与 apply() 方法类似,也负责对参数进行处理,只是该方法不会返回处理结果。
- XxxSupplier,供给型接口。语法:public interface Supplier<T>{public T get()}。这类接口通常含有 getAsXxx() 接口。该方法不需要输入参数,该方法会按照某种逻辑算法(逻辑算法由 lambda 表达式实现)返回一个数据。
- XxxPredicate,断言型接口。语法:public interface Predicate<T>{public boolean test(T t);}。该方法通常用来对参数进行某种判断是否满足特定条件,经常用于筛选数据。
功能型接口
import java.util.function.Function;
public class Demo {
public static void main(String[] args) {
Function<String, Boolean> fun = "hello world"::startsWith;
System.out.println(fun.apply("hello"));
}
}
详细说明
/**
* Function测试
*/
public static void functionTest() {
Function<Integer, Integer> f = i -> i + 10;
Function<Integer, Integer> g = s -> s * 2;
/**
* 下面表示在执行F时,先执行G,并且执行F时使用G的输出当作输入。
* 相当于以下代码:
* Integer a = g.apply(1);
* System.out.println(f.apply(a));
*/
System.out.println(f.compose(g).apply(1));
/**
* 表示执行F的Apply后使用其返回的值当作输入再执行G的Apply;
* 相当于以下代码
* Integer a = f.apply(1);
* System.out.println(g.apply(a));
*/
System.out.println(f.andThen(g).apply(1));
/**
* identity方法会返回一个不进行任何处理的Function,即输出与输入值相等;
*/
System.out.println(Function.identity().apply("a"));
}
消费型接口
import java.util.function.Consumer;;
class MyDemo{
public void print(String str) {
System.out.println(str);
}
}
public class Demo {
public static void main(String[] args) {
Consumer<String> con = new MyDemo()::print;
con.accept("Good!");
Consumer<String> con1 = System.out::println;
con1.accept("Nice!");
}
}
详细说明
public static void consumerTest() {
Consumer f = System.out::println;
Consumer f2 = n -> System.out.println(n + "-F2");
//执行完F后再执行F2的Accept方法
f.andThen(f2).accept("test");
//连续执行F的Accept方法
f.andThen(f).andThen(f).andThen(f).accept("test1");
}
供给型接口
import java.util.function.Supplier;
public class Demo {
public static void main(String[] args) {
Supplier<String> sup = "hello".substring(2, 5)::toUpperCase;
String str = sup.get();
System.out.println(str);
}
}
断言型接口
import java.util.function.Predicate;
public class Demo {
public static void main(String[] args) {
Predicate<String> pre = "Good"::endsWith;
System.out.println(pre.test("od"));
}
}
详细说明
/**
* Predicate测试
*/
private static void predicateTest() {
Predicate<String> p = o -> o.equals("test");
Predicate<String> g = o -> o.startsWith("t");
/**
* negate: 用于对原来的Predicate做取反处理;
* 如当调用p.test("test")为True时,调用p.negate().test("test")就会是False;
*/
Assert.assertFalse(p.negate().test("test"));
/**
* and: 针对同一输入值,多个Predicate均返回True时返回True,否则返回False;
*/
Assert.assertTrue(p.and(g).test("test"));
/**
* or: 针对同一输入值,多个Predicate只要有一个返回True则返回True,否则返回False
*/
Assert.assertTrue(p.or(g).test("ta"));
}
猜你喜欢
- 2024-11-30 Java开发「函数式编程」——Lambda表达式
- 2024-11-30 玩转java8 lambda表达式三之对象方法引用
- 2024-11-30 Java 中的 Supplier:让数据生成更灵活
- 2024-11-30 Java 中的 Predicate:让判断逻辑更清晰灵活
- 2024-11-30 Java8精华-函数式编程(一)读完这篇,你将彻底理解
- 2024-11-30 你知道实现一个JAVA接口有几种方式吗?配合lambda更加意想不到
- 2024-11-30 java8精华-函数式编程-Predicate(四)
- 2024-11-30 巧妙应用 Java 的 Functional Interface:让代码更简洁、更灵活
- 2024-11-30 函数式接口编程真没那么难,简单几行让你的代码更优雅
- 2024-11-30 初窥函数式接口,不会取标题,没有噱头,全是干货
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)