java8——lambda expression
来源:互联网 发布:网络招生技巧 编辑:程序博客网 时间:2024/06/08 18:02
几点总结:
- 一个lambda表达式是一个带有参数的代码块
- 当你想要代码块在以后某个时间点执行时,可以使用lambda表达式
- lambda表达式可以被转换为函数式接口
- lambda表达式可以在闭包作用域中有效地访问final变量
- 方法和构造器引用可以引用方法或构造器,但无需调用他们(?)
===
1.1 为什么要使用lambda
先来看看类似的用法:
class Worker implements Runnable{ @Override public void run() { for (int i = 0; i < 5; i++) { doWork(); }}Worker w = new Worker();new Thread(w).start;
上述这段代码的关键在于,run方法中包括了你希望在另一线程中执行的代码。
class LengthComparator implements Comparator<String>{ public int compare(String first, String second){ return Integer.compare(first.length(). second.length()); }}Arrays.sort(strings, new LengthComparator());
你给sort方法传递了一段需要比较元素的代码,并不需要关心其如何在被整合的代码中实现。
tip:上面的比较,并没有简单地使用x-y这种比较式,防止当x与y符号相反时,极端情况下的溢出
Thread thread1 = new Thread(new Runnable() { // 匿名实现类,会得到提示可以转换成lambda表达式 @Override public void run() { ...... } },"thread1");
总结:使用lambda是为了更好地实现向其他代码传递一段代码,以及简化编写。
1.2 lambda表达式的语法
(String first, String second) -> Integer.compare(first.length(), second.length())
参数,箭头,以及一个表达式(或代码块,如下)
指定了必须传给代码的所有变量
(String first, String second) -> { if (first.length() < second.length()) return -1; else if (first.length() > second.length()) return 1; else return 0; }
- 没有参数,括号中可以为空
- 一个参数,可以省略括号
- 可以省略参数类型,如果可以从上下文中推倒
- 不需要为lambda表达式写返回类型
1.3函数式接口
对于只包含一个抽象方法的接口,可以通过lambda表达式来创建该接口的对象。
Arrays.sort(strings, (a, b) -> Integer.compare(a.length(), b.length()));
接口Comparator中,除了compare方法,还有一个equals方法也没有方法体,但它不是抽象方法,默认实现是Object类中的equals。同时,java8中,接口可以声明非抽象的方法(default关键字)
@FunctionalInterface,包含此注解的接口,都是函数式接口。当我们编写函数式接口时,也可加上此注解,编译器会检查是否符合要求。
最后,应注意检查lambda表达式中的方法是否会抛出异常。
1.4方法引用
调用已存在的方法
几种格式:
对象::实例方法
类::静态方法
类::实例方法
super::实例方法(引用父类)
//使用lambda表达式和类的静态方法Arrays.sort(persons, (o1, o2) -> Person.compareByAge(o1,o2));//使用方法引用//引用的是类的静态方法Arrays.sort(persons, Person::compareByAge);
//使用lambda表达式//对象的实例方法Arrays.sort(persons,(a,b)->provider.compareByAge(a,b));//使用方法引用//引用的是对象的实例方法Arrays.sort(persons, provider::compareByAge);
//使用lambda表达式和类型对象的实例方法Arrays.sort(stringsArray,(s1,s2)->s1.compareToIgnoreCase(s2));//使用方法引用//引用的是类型对象的实例方法Arrays.sort(stringsArray, String::compareToIgnoreCase);
1.5构造器引用
方法名是new,对象::new
对于拥有多个构造器的类,选用哪个构造器取决于上下文。
1.6 变量作用域
public static void repeat(String text){ Runnable r = () -> { System.out.print(text); text = "aaa" // error! }; new Thread(r).start(); }
lambda表达式可以捕获闭合作用域中的变量值。但不能改变已捕获变量(传入变量)的值。非lambda表达式同样不可以。所以,获取的变量必须是final或者表现为final(即不能修改)。
注:不可变约束只作用于局部变量上,如果是一个实例变量或者内部类的静态变量,如在Runnable中定义的变量,即可被改变。
1.8中,内部类可以捕获闭合作用域的值,操作要求同上。
1.7默认方法
即之前提到过的接口中加了default关键字的方法。
实现了该接口的类可以选择保留原实现或者重写。
Q: 当一个接口定义了一个默认方法,而另一个接口或父类又定义了同名的方法,jdk会怎么处理?
1.如果是父类中发生重复,则选择父类中的方法。
2.如果是两个接口中发生冲突,则必须在实现中覆盖该方法来解决冲突。
1.8接口中的静态方法
在java8中,可以为接口添加静态方法。
===
练习部分:
- java8——lambda expression
- Java8新特性——Lambda表达式
- Java8新特性——lambda表达式
- Java8新特性——Lambda
- Java8 特性—— Lambda 表达式
- Java8之——Lambda表达式入门
- java8——Coding with lambda
- Java8 实战学习 — Lambda 表达式
- Java8学习笔记 — 【Lambda表达式】
- Java8 Easy Introduction — 1. Lambda
- Java8新特性——Lambda表达式(一)
- java8初体验——optional、lambda、stream、map
- java8 Lambda
- Java8 Lambda
- Java8 Lambda
- java8 lambda
- java8-lambda
- java8-lambda
- MyBatis+MySQL 返回插入的主键ID
- C#调用C++动态库(dll)
- unity3d各平台的路径问题
- GA遗传算法入门到掌握
- WifiP2pSettings工作流程
- java8——lambda expression
- hadoop初读--setInputFormatClass
- ExoPlayer 的小解析
- volatile 浅显描述
- Fiddler:读取Response的body写入本地文件
- GA遗传算法(Genetic Algorithm)
- TimingWheel[时间轮]介绍
- Android Web开发调试之Chrome远程调试
- App的启动过程(5)ViewTree遍历中最后一步的Draw