1 总体说明
Java8新特性概述
函数式接口
Lambda表达式(闭包)
2 Java8新特性概述
Oracle公司于2014年3月发布了Java8正式版,该版本是自JDK5.0以来最具革命性的版本。
Java8为Java语言、编译器、类库和JVM带来了大量的新特性。接下来的内容将会详细说明Java8在Java语言方面的新特性以及它们的使用场景。
3 函数式接口
Java8引入的一个核心概念是函数式接口(Functional Interfaces):如果一个接口定义一个唯一的抽象方法,那么这个接口就是函数式接口。同时引入一个新注解:@FunctionalInterface,在函数式接口上方使用该注解声明此接口为函数式接口,也就意味着该接口只能有唯一的抽象方法。
在线程的创建时通常都采用实现Runnable接口,然后重写抽象的run方法来定义线程任务。该接口就是一个函数式接口.
@FunctionalInterface //函数式接口注解,此接口中不能添加其他抽象方法
public interface Runnable {
/*该方法由子类实现,定义线程执行的业务逻辑*/
public abstract void run();
}
那么问题来了,函数式接口有啥用呢? 请看下面的Lambda表达式
4 Lambda表达式(闭包)
函数式接口的重要属性:可以使用Lambda实例化它们。
Lambda的引入给开发者带来不少的好处:在Java8之前,匿名内部类,监听器和事件处理器的使用都显得很冗长,代码可读性很差,Lambda表达式的应用则使得代码变得更加紧凑,可读性增强。(前提条件是你要理解Lambda表达式写法的含义)而且Lambda表达式使得并行操作大集合变得很方便,可以充分发挥多核CPU的优势,更易于为多核处理器编写代码;
4.1 Lambda表达式的组成
第一部分:一个括号内用逗号分隔的形式参数,参数是函数式接口方法里的参数。
第二部分:为一个箭头符号:->
第三部分:方法体,可以是表达式或者是代码块,如果方法体为表达式,该表达式的值作为返回值返回,如果方法体为代码块,需要使用{}包裹起来,切需要一个return返回值,但若函数式接口的方法返回值为void,则无需返回值。
Lambda表现形式为(parmeters) -> expression 或者 (parmeters) -> { statements; }
4.2 Lambda表达式的最佳实践:替换匿名内部类
下面使用Runnable接口为例,比较Lambda接口和匿名内部类的写法
使用()->{}代替了匿名内部类
LambdaSample类中包含了两个方法,分别是使用lambda表达式和匿名内部类计算1-10之间的偶数和,相对于匿名内部类而言,Lambda表达式更加简洁。
package tony.javacore.jdk8.lambda;
import static tony.javacore.util.io.PrintUtils.*;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
/**
* <p>Lambda表达式的使用和匿名内部类的对比</p>
* @author tony [email protected]
* @project_name JavaCore
* @package_name tony.javacore.jdk8.lambda
* @file_name LambdaSampleVSAnonymous.java
* @see
* @version 2015年9月6日下午9:36:49
* @since JDK8.0u45
*/
public class LambdaSampleVSAnonymous{
/**
* 使用lambda表达式计算1-10之间的偶数和
* @version 2015年9月6日下午9:58:11
* @since
*/
public static void getSumWithLambda(){
Runnable runnable=()->{
println("使用lambda表达式创建runnable对象并计算1-10之间的偶数和");
int sum =0;
for(int i=1;i<=10;i++){
if(i%2==0){
sum+=i;
}
}
println("1-10之间的偶数和为 : "+sum);
};
Thread thread =new Thread(runnable);
thread.start();
//计算完毕之后暂停2秒钟
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 使用匿名内部类计算1-10之间的偶数和
* @version 2015年9月6日下午10:00:31
* @since
*/
public static void getSumWithAnonymous(){
Runnable runnable =new Runnable() {
@Override
public void run() {
println("使用匿名内部类式创建runnable对象并计算1-10之间的偶数和");
int sum =0;
for(int i=1;i<=10;i++){
if(i%2==0){
sum+=i;
}
}
println("1-10之间的偶数和为 : "+sum);
}
};
Thread thread =new Thread(runnable);
thread.start();
}
public static void main(String[] args) {
getSumWithLambda();
getSumWithAnonymous();
}
}
/**
* 使用lambda表达式创建runnable对象并计算1-10之间的偶数和
* 1-10之间的偶数和为 : 30
* 使用匿名内部类式创建runnable对象并计算1-10之间的偶数和
* 1-10之间的偶数和为 : 30
*/
4.3 Lambda表达式最佳实践:遍历常用数据结构
package tony.javacore.jdk8.lambda;
import static tony.javacore.util.io.PrintUtils.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* <p>两种遍历集合的方式</p>
* @author tony [email protected]
* @project_name JavaCore
* @package_name tony.javacore.jdk8.lambda
* @file_name ForeachVSLambda.java
* @see
* @version 2015年9月10日 上午10:14:10
* @since JDK8.0u45
*/
public class ForeachVSLambda {
/**
* JDK1.5的foreach遍历数据结构List的方式
* @param list
*/
public static void foreachCollection(Collection<String> collection){
for(String content:collection){
println("content : "+content);
}
}
/**
* 使用JDK1.8以后新增的默认方法forEach和lambda遍历数据结构List
* @param list
*/
public static void lambdaForEachCollection(Collection<String> collection){
collection.forEach((content )->{
println("content : "+content);
});
}
/**
* foreach循环遍历map
* @param map
*/
public static void foreachMap(Map<String, Integer> map){
for(Map.Entry<String,Integer> entry:map.entrySet()){
println("key : "+entry.getKey() +" value : "+entry.getValue());
}
}
/**
* 使用JDK1.8以后新增的默认方法forEach和lambda遍历数据结构Map
* @param map
*/
public static void lambdaForEachMap(Map<String, Integer> map){
map.forEach((key,value)->{
println("key : "+key +" value : "+value);
});
}
public static void main(String[] args) {
List<String> list =new ArrayList<>();
list.add("Java");
list.add("Scala");
list.add("JPython");
foreachCollection(list);
printFlag();
lambdaForEachCollection(list);
Map<String, Integer> map =new HashMap<String, Integer>();
map.put("语文", 105);
map.put("数学", 105);
map.put("英语", 105);
foreachMap(map);
printFlag();
lambdaForEachMap(map);
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。