学习lambda函数, 首先我们来了解下java8之后接口(Interface)和之前有什么不一样
1.我们知道, 在java8之前, 接口由两个部分组成, 抽象方法和常量(成员变量默认修饰符public static final, 成员方法默认修饰符public absolute)
在java8之后
接口新增了默认方法(default), 静态方法以及java9支持的私有方法
总结下接口可能的组成部分
1.抽象方法 2.常量 3.默认方法(Java8) 4.静态方法(java8) 5.私有方法(java9)
/** * 由于本人使用的是java8, 故私有方法不能演示, 有兴趣的同学可以试一试 * * @author wenfucheng */ public interface Calculator { default void defaultMethod(){ System.out.println("接口中的默认方法"); } static void staticMethod(int a, int b){ System.out.println("接口中的静态方法"); } int sum (int a, int b); }
以上就是对java8以后接口变化的介绍, 接下来我们言归正传
首先我们来看一段代码
public class CalculatorDemo { public static void main(String[] args) { calculate(new Calculator() { @Override public int sum(int a, int b) { return a+b; } }); } public static void calculate(Calculator calculator){ System.out.println(calculator.sum(10,20)); } }
相信这段代码大家都不陌生, 没错, 就是匿名内部类, 以前我们直接new一个接口的时候需要使用匿名内部类实现接口里所有的方法
这是IDE已经提示这个地方可以替换为lambda函数了, 我们来看一下替换为lambda函数之后的代码
public static void main(String[] args) { // 原始版 calculate((int x,int y) ->{return x+y;}); // 精简版 calculate((x,y) -> x+y); }
没错, 只要一行就解决了, 是不是很easy, 这一行代码和上面的功能一毛一样(lambda自身有一个上下文推断功能)
其实这个地方如果lambda里面的代码在另一个地方已经出现过, 我们只需要复用就行
public static void main(String[] args) { calculate(Math::addExact); }
那么问题来了, 什么情况下可以用lambad函数呢, 只要能用到匿名内部类的地方都可以用吗? 当然不是
要用lambda, 首先得有函数式接口, Java8当中使用lambda表达式的前提是: 必须有"函数式接口"
什么是函数式接口呢? 有且仅有一个抽象方法的接口就被称作函数式接口
那么如何万无一失地检测一下当前接口是不是函数式接口呢? 用一个固定的格式写在public interface之前一行即可
@FunctionalInterface
public interface 函数式接口名称{...
}
就像之前我们提到的这个接口
@FunctionalInterface public interface Calculator { default void defaultMethod(){ System.out.println("接口中的默认方法"); } static void staticMethod(int a, int b){ System.out.println("接口中的静态方法"); } int sum (int a, int b); }
接下来我们来学习下lambda表达式另一个强大的地方stream流
/** * 需求: 将list里面的字符串切割, 分离数字和字符串, 然后将字符串转成数字, * 然后过滤出数字大于20的, 最后再转成一个集合 */
public static void main(String[] args) { List<String> list = Arrays.asList("11,北京","22,上海","33,广州","44,深圳"); /** * 通过stream流改造后的list为[22,33,44] */ List<Integer> collect = list.stream().map(s -> s.split(",")[0]). map(Integer::parseInt).filter(s -> s > 20).collect(Collectors.toList()); /** * 通过parallelStream(并发流), 效率会更高 */ List<Integer> collect1 = list.parallelStream().map(s -> s.split(",")[0]). map(Integer::parseInt).filter(s -> s > 20).collect(Collectors.toList()); }
我们看下以上steam涉及到的操作, map(映射) 将stream里面的元素进行映射转换
filter(过滤) 传递一个返回boolean类型的函数
collect 将流转成集合
试想下, 如果我们用传统的list实现以上需求, 需要哪些步骤, 恐怕不是一行代码能解决的吧
这个stream流用起来真的是太爽了!
好了, 以上就是关于lambda的介绍和使用, 欢迎小伙伴指正和补充!