Java 基础(Lambda表达式 和 函数式 Functional 接口)
Lambda表达式
函数式 Functional 接口
- 只包含一个抽象方法的接口,称为函数式接口。
- 你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。
- 我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
- 在 java.util.function 包下定义了Java 8的丰富的函数式接口
- Java 从诞生日起就是一直倡导 “一切皆对象”,在Java里面面向对象(OOP)编程是一切。但是随着python、scala等语言的兴起和新技术的挑战,Java不得不做出调整以便支持更加广泛的技术要求,也即 java 不但可以支持OOP还可以支持OOF(面向函数编程)
- 在函数式编程语言当中,函数被当做一等公民对待。在将函数作为一等公民的编程语言中,Lambda表达式的类型是函数。但是在Java8中,有所不同。在Java8中,Lambda表达式是对象,而不是函数,它们必须依附于一类特别的对象类型——函数式接口。
- 简单的说,在Java8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说,只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。
- 所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。
Java 内置四大核心函数式接口
其他接口
LambdaTest.java
package com.klvchen.java1; import org.junit.Test; import java.util.Comparator; public class LambdaTest { @Test public void test1(){ Runnable r1 = new Runnable() { @Override public void run() { System.out.println("我爱北京天安门"); } }; r1.run(); System.out.println("**********************************"); Runnable r2 = () -> System.out.println("我爱北京故宫"); r2.run(); } @Test public void test2(){ Comparator<Integer> com1 = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1, o2); } }; int compare1 = com1.compare(12, 21); System.out.println(compare1); System.out.println("***************************************"); Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1,o2); int compare2 = com2.compare(32, 21); System.out.println(compare2); System.out.println("***************************************"); //方法引用 Comparator<Integer> com3 = Integer :: compare; int compare3 = com3.compare(32, 21); System.out.println(compare3); } }
LambdaTest1.java
package com.klvchen.java1; import org.junit.Test; import java.util.ArrayList; import java.util.Comparator; import java.util.function.Consumer; /* Lambda表达式的使用 1.举例: (o1,o2) -> Integer.compare(o1,o2); 2.格式: ->左边: Lambda形参列表的参数类型可以省略(类型推断);如果Lambda形参列表只有一个参数,其一对()也可以省略 ->右边: Lambda体应该使用一对{}包裹;如果Lambda体只有一条执行语句(可能是return语句),可以省略这一对{}和return关键字 3.Lambda 表达式的使用:(分为6种情况) 4.Lambda 表达式的本质:作为接口的实例 5.如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口 6.所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。 */ public class LambdaTest1 { // 语法格式一:无参,无返回值 @Test public void test1(){ Runnable r1 = new Runnable() { @Override public void run() { System.out.println("我爱北京天安门"); } }; r1.run(); System.out.println("*****************************"); Runnable r2 = () -> System.out.println("我爱北京故宫"); r2.run(); } //语法格式二:Lambda需要一个参数,但是没有返回值。 @Test public void test2(){ Consumer<String> con = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }; con.accept("谎言和誓言的区别是什么?"); System.out.println("*****************************"); Consumer<String> con1 = (String s) -> { System.out.println(s); }; con1.accept("一个是听得人当真了,一个是说的人当真了"); } //语法格式三:数据类型可以省略,因为可由编译器推断得出,称为"类型推断" @Test public void test3(){ Consumer<String> con1 = (String s) -> { System.out.println(s); }; con1.accept("一个是听得人当真了,一个是说的人当真了"); System.out.println("*****************************"); Consumer<String> con2 = (s) ->{ System.out.println(s); }; con2.accept("一个是听得人当真了,一个是说的人当真了"); } @Test public void test4(){ ArrayList<String> list = new ArrayList<>();//类型推断 int[] arr = {1, 2, 3};//类型推断 } //语法格式四: Lambda若只需要一个参数时,参数的小括号可以省略 public void test5(){ Consumer<String> con1 = (s) -> { System.out.println(s); }; con1.accept("一个是听得人当真了,一个是说的人当真了"); System.out.println("*****************************"); Consumer<String> con2 = s -> { System.out.println(s); }; con2.accept("一个是听得人当真了,一个是说的人当真了"); } //语法格式五:Lambda需要两个或以上的参数,多条执行语句,并且可以有返回值 @Test public void test6(){ Comparator<Integer> com1 = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { System.out.println(o1); System.out.println(o2); return o1.compareTo(o2); } }; System.out.println(com1.compare(12,21)); System.out.println("*****************************"); Comparator<Integer> com2 = (o1,o2) -> { System.out.println(o1); System.out.println(o2); return o1.compareTo(o2); }; System.out.println(com2.compare(12,6)); } //语法格式六:当Lambda体只有一条语句时,return 与大括号若有,都可以省略 @Test public void test7(){ Comparator<Integer> com1 = (o1, o2) -> { return o1.compareTo(o2); }; System.out.println(com1.compare(12, 6)); System.out.println("******************************************************"); Comparator<Integer> com2 = (o1, o2) -> o1.compareTo(o2); System.out.println(com2.compare(12, 21)); } @Test public void test8(){ Consumer<String> con1 = s -> { System.out.println(s); }; con1.accept("一个是听得人当真了,一个是说的人当真了"); System.out.println("******************************************************"); Consumer<String> con2 = s -> System.out.println(s); con2.accept("一个是听得人当真了,一个是说的人当真了"); } }
LambdaTest2.java
package com.klvchen.java1; /* java内置的4大核心函最式接口 消费型接口 Consumer<T> void accept(T t) 供给型接口 Supplier<T> T get() 函数型接口 Function<T,R> R apply(T t) 断定型接口 Predicate<T> booLean test(T t) */ import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import java.util.function.Predicate; public class LambdaTest2 { @Test public void test1(){ happyTime(500, new Consumer<Double>() { @Override public void accept(Double aDouble) { System.out.println("学习太累了,去天上人间买了瓶矿泉水,价格为: " + aDouble); } }); System.out.println("**************************************************"); happyTime(400, money -> System.out.println("学习太累了,去天上人间买了瓶矿泉水,价格为: " + money)); } public void happyTime(double money, Consumer<Double> con) { con.accept(money); } @Test public void test2(){ List<String> list = Arrays.asList("北京","南京","天津","东京","西京","普京"); List<String> filterStrs = filterString(list, new Predicate<String>() { @Override public boolean test(String s) { return s.contains("京"); } }); System.out.println(filterStrs); List<String> filterStrs1 = filterString(list, s -> s.contains("京")); System.out.println(filterStrs1); } //据给定的规剩,过滤集合中的字符串。此规则由Predicate的方法决定 public List<String> filterString(List<String> list, Predicate<String> pre){ ArrayList<String> filterList = new ArrayList<>(); for (String s : list) { if (pre.test(s)){ filterList.add(s); } } return filterList; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY