一、Lambda表达式
Lambda表达式其实是一种借鉴,在其他的语言中早已出现。python属于函数式编程思维,Lambda在里面是函数,但是java提倡“万事万物皆对象”,所以在java中,Lambda表达式不是函数而是对象。
Lambda表达式的本质
Lambda的本质是java中接口的一个实例(接口的实现类的具体对象)。可通过下图形象理解。
Lambda表达式语法
- 语法
-> :箭头操作符,Lambda表达式操作符。
->左侧:Lambda形参列表,->对应->接口中的抽象方法的形参列表。
->右侧:重写方法的方法的具体内容。
- 具体格式
1、无参,无返回值
2、有一个参数、无返回值
3、多个参数、有返回值
4、总结
->左边:
(1)因为可以进行类型推断,所以可以不用写形参的类型;
(2)如果只有一个参数,()可以不写。
->右边:
(1){}将方法体的具体内容包裹起来;
(2)方法体只有一条语句,{}可以不写;
(3)如果方法体只有一条并且这条语句就是返回语句,return关键字可以不写。
二、函数是接口
Lambda表达式是接口的实现类的对象,因此Lambda需要依赖一个接口,那么这个接口有什么要求吗?
Lambda所依赖的接口的要求:要求这个接口必须只有一个抽象方法。
- 函数是接口:(1)只有一个抽象方法;(2)jdk8以后可以有非抽象方法。
- 自定义函数式接口
在自定义函数式接口前面加上一个注解:@FunctionalInterface,如果检测到多个抽象方法是会报错
- 四个常用的内置函数式接口
有一些接口系统已经为我们提供好,没有必要自己再去写。
java8中的java.util.function包下:
- 消费型接口:Consumer —> void accept(T t) 传入参数,没有返回值类型;
- 断定型接口:Predicate —> boolean test(T t) 传入T,返回布尔类型;
- 函数型接口:Function —> R apply(T t) 传入T,得到R;
- 供给型接口:Supplier —> T get() 不用传入参数,有返回值
- 内置函数式接口举例
- 消费型接口:Consumer —> void accept(T t) 传入参数,没有返回值类型;
import java.util.function.Consumer; //2、使用内置的Consumer接口 class Demo1{ public static void main(String[] args) { Consumer<Double> sm = money -> System.out.println("花了"+money+"块钱买书"); buySomething(100,sm); } public static void buySomething(double money,Consumer sm){ sm.accept(money); } }
- 断定型接口:Predicate —> boolean test(T t) 传入T,返回布尔类型;
需求:从给定的字符串集合中挑选出长度大于5的字符串。
(1)未使用Lambda表达式代码
/** * 从给定的字符串集合中挑选出长度大于5的字符串。 */ public class PredicateInterfaceTest { public static void main(String[] args) { List<String> strs = Arrays.asList("faefwaef", "dew", "fwe21a", "dfwa", "as", "1fafa"); List<String> newStrs = getFilterString(strs, new Predicate<String>() { @Override public boolean test(String str) { return str.length()>5; } }); for (String newStr : newStrs) { System.out.println(newStr); } } //返回字符串长度大于5的字符串集合 public static List<String> getFilterString(List<String> strs, Predicate<String> sp){ //思路:把符合条件的字符串放到一个新的集合,然后返回 ArrayList<String> newStrs = new ArrayList<>(); for (String str : strs) { if (sp.test(str)) { newStrs.add(str); } } return newStrs; } }
(2)使用Lambda表达式后的代码
/** * 从给定的字符串集合中挑选出长度大于5的字符串。 */ public class PredicateInterfaceTest { public static void main(String[] args) { List<String> strs = Arrays.asList("faefwaef", "dew", "fwe21a", "dfwa", "as", "1fafa"); List<String> newStrs = getFilterString(strs, (str)->str.length()>5); for (String newStr : newStrs) { System.out.println(newStr); } } //返回字符串长度大于5的字符串集合 public static List<String> getFilterString(List<String> strs, Predicate<String> sp){ //思路:把符合条件的字符串放到一个新的集合,然后返回 ArrayList<String> newStrs = new ArrayList<>(); for (String str : strs) { if (sp.test(str)) { newStrs.add(str); } } return newStrs; } }