您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 深圳分类信息网,免费分类信息发布

深圳Java培训学习:Java8.0新特性之Lambda表达式--【千锋】

2019/11/7 17:52:16发布144次查看
深圳java培训学习:java8.0新特性之lambda表达式--【千锋】
前言
java 8 已经发布很久了,很多报道表明java 8 是一次重大的版本升级。本篇文章,主要给大家介绍的是lambda表达式。
lambda表达式
lambda表达式(也称为闭包)是java 8中最大和最令人期待的语言改变。它允许我们将函数当成参数传递给某个方法,或者把代码本身当作数据处理:函数式开发者非常熟悉这些概念。
很多jvm平台上的语言(groovy、scala等)从诞生之日就支持lambda表达式,但是java开发者没有选择,只能使用匿名内部类代替lambda表达式。
lambda的设计耗费了很多时间和很大的社区力量,最终找到一种折中的实现方案,可以实现简洁而紧凑的语言结构。而lambda表达式的使用需要和函数式接口结合。
1.函数式接口
1.1.概念
函数式接口在java中是指:有且仅有一个抽象方法的接口。函数式接口,即适用于函数式编程场景的接口。而java中的函数式编程体现就是lambda,所以函数式接口就是可 以适用于lambda使用的接口。只有确保接口中有且仅有一个抽象方法,java中的lambda才能顺利地进行推导。备注:“语法糖”是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实 底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,java中的lambda可以被当做是匿名内部 类的“语法糖”,但是二者在原理上是不同的。
1.2,格式
只要确保接口中有且仅有一个抽象方法即可:
1.修饰符 interface 接口名称 {           
2.    public abstract 返回值类型 方法名称(可选参数信息);  
3.}  
1.3 @functionalinterface注解
与 @override 注解的作用类似,java 8中专门为函数式接口引入了一个新的注解:@functionalinterface 。该注解可用于一个接口的定义上:
1.@functionalinterface  
2.public interface myfunctionalinterface {  
3.    void mymethod();  
4.} 
一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注 意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样.
2.函数式接口的使用
2.1函数式接口作为参数,方法不带参数
1.//定义函数式接口  
2.public interface myinterface{  
3.      
4.    public abstract void show();  
5.      
6.}  
7.  
8.//使用(匿名内部类对象/函数式)   
9.public class demo01 {  
10.  
11.    public static void main(string[] args) {  
12.        method01(new myinterface01() {  
13.  
14.            @override  
15.            public void show() {  
16.                system.out.println("你好,函数式接口");  
17.            }  
18.        });  
19.        // 函数式  
20.        method01(() -> {  
21.            system.out.println("你好,函数式接口");  
22.        });  
23.        // 函数式简写(如果方法体中只有一句代码)  
24.        method01(() -> system.out.println("你好,函数式接口"));  
25.    }  
26.  
27.    public static void method01(myinterface01 inter) {  
28.        inter.show();  
29.    }  
30.  
31.} 
函数式接口的优势
函数式接口比匿名内部类对象产生更少的字节码对象,提升java执行效率.
2.2, 函数式接口作为参数,方法带参数
1.//定义函数式接口  
2.    public interface myinterface02 {  
3.  
4.        public abstract void show(string msg1, string msg2);  
5.  
6.    }  
7.  
8.    //使用函数式接口  
9.    public static void main(string[] args) {  
10.        //匿名内部类对象  
11.        method01(new myinterface02() {  
12.  
13.            @override  
14.            public void show(string msg1, string msg2) {  
15.                system.out.println(msg1 + msg2);  
16.            }  
17.        });  
18.        //函数式完整  
19.        method01((string msg1, string msg2) -> {  
20.            system.out.println(msg1 + msg2);  
21.        });  
22.        //函数式简写  
23.        method01((msg1, msg2) -> system.out.println(msg1 + msg2));  
24.  
25.    }  
26.  
27.    public static void method01(myinterface02 inter) {  
28.        inter.show("hello", "函数式");  
29.    }
2.3, 函数式接口作为返回值,方法不带参数
1.   //定义函数式接口  
2.   public interface myinterface02 {  
3.  
4.    public abstract void show(string msg1, string msg2);  
5.  
6.   }  
7.public static void main(string[] args) {  
8.  
9.    getinter1().show("你好", "函数式");  
10.    getinter2().show("你好", "函数式");  
11.  
12.}  
13.  
14.// 函数式完整  
15.public static myinterface02 getinter1() {  
16.  
17.    return (string msg1, string msg2) -> {  
18.        system.out.println(msg1 + msg2);  
19.    };  
20.}  
21.  
22.// 函数式简写  
23.public static myinterface02 getinter2() {  
24.  
25.    return (msg1, msg2) -> system.out.println(msg1 + msg2);  
26.}  
3.函数式编程应用场景
3.1,概念
在兼顾面向对象特性的基础上,java语言通过lambda表达式使用函数式接口,就叫做函数式编程
3.2, 使用lambada作为参数
如果抛开实现原理不说,java中的lambda表达式可以被当作是匿名内部类的替代品。如果方法的参数是一个函数 式接口类型,那么就可以使用lambda表达式进行替代。
1.public class demo04runnable{  
2.    private static void startthread(runnable task){    
3.        new thread(task).start();   
4.    }        
5.    public static void main(string[] args) {   
6.        startthread(()‐>system.out.println("线程执行"));   
7.    }   
8.}  
3.3, 使用函数式接口作为返回值
如果一个方法的返回值类型是一个函数式接口,那么就可以直接返回一个lambda表达式。
1.public class demo06comparator {  
2.  
3.    private static comparator<integer> getcomparator(){  
4.        return (num1,num2)‐> num1 - num2;  
5.    }  
6.      
7.    public static void main(string[] args) {  
8.        integer[] array = {3,2,1};   
9.        arrays.sort(array, getcomparator());   
10.        //遍历数组  
11.    }   
12.} 
3.4, 函数式接口的方法有返回值
1.public static void main(string[] args) {  
2.  
3.        showmsg(new myinterface03() {  
4.  
5.            @override  
6.            public string getmsg() {  
7.                return "hello functional interface";  
8.            }  
9.        });  
10.  
11.        // lambada表达式  
12.        showmsg(() -> {  
13.  
14.            return "hello1 functional interface";  
15.        });  
16.  
17.        // lambda表达式简写  
18.        showmsg(() -> "hello1 functional interface");  
19.  
20.    }  
21.  
22.    public static void showmsg(myinterface03 inter) {  
23.        string msg = inter.getmsg();  
24.        system.out.println(msg);  
25.    } 
4.常用函数式接口(supplier接口)
jdk提供了大量常用的函数式接口以丰富lambda的典型使用场景,它们主要在 java.util.function 包中被提供。下面是简单的几个接口及使用示例。
4.1,supplier接口  
java.util.function.supplier<t> 接口仅包含一个无参的方法:t get() 。用来获取一个泛型参数指定类型的对象数据。由于这是一个函数式接口,这也就意味着对应的lambda表达式需要“对外提供”一个符合泛型类型的对象数据
4.2,基本使用
1.private static string getstring(supplier<string> function ){  
2.    return function.get();  
3.}  
4.public static void main(string[] args){  
5.    string msga="hello";  
6.    string msgb="world";  
7.    system.out.println(getstring(()->msga+msgb));  
8.}  
4.2,综合案例
需求:使用 supplier 接口作为方法参数类型,通过lambda表达式求出int数组中的最大值。提示:接口的泛型请使用 java.lang.integer 类。
1.public static void main(string[] args) {  
2.    integer max = getmax(()->{  
3.        integer[] nums = {1,2,3,4};  
4.        int max2 = nums[0];  
5.        for (integer num : nums) {  
6.            if(max2 < num){  
7.                max2 = num;  
8.            }  
9.        }  
10.        return max2;  
11.    });  
12.    system.out.println(max);  
13.}  
14.  
15.public static integer getmax(supplier<integer> supplier){  
16.    return supplier.get();  
17.}  
5.常用函数式接口(consumer接口)
5.1,consumer接口  
java.util.function.consumer<t> 接口则正好与supplier接口相反,它不是生产一个数据,而是消费一个数据, 其数据类型由泛型决定
5.2,accept方法    
consumer 接口中包含抽象方法 void accept(t t) ,意为消费一个指定泛型的数据。基本使用如:
1.public static void main(string[] args) {  
2.    consumestring((msg)->system.out.println(msg));  
3.}  
4.  
5.  
6.public static void consumestring(consumer<string> consumer){  
7.     consumer.accept("hello");  
8.}  
5.3, andthen方法   
如果一个方法的参数和返回值全都是 consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作, 然后再做一个操作,实现组合。而这个方法就是 consumer 接口中的default方法 andthen
1.default consumer<t> andthen(consumer< super t> after) {  
2.    objects.requirenonnull(after);  
3.    return (t t) -> { accept(t); after.accept(t); };  
4.}  
注: java.util.objects 的 requirenonnull 静态方法将会在参数为null时主动抛出 nullpointerexception 异常。这省去了重复编写if语句和抛出空指针异常的麻烦。
需求:先打印大写hello,再打印小写hello
1.public static void main(string[] args) {  
2.    consumestring((msg) -> system.out.println(msg.touppercase()),   
3.            (msg) -> system.out.println(msg.tolowercase()));  
4.}  
5.  
6.public static void consumestring(consumer<string> consumer1, consumer<string> consumer2) {  
7.    consumer1.andthen(consumer2).accept("hello");  
8.}  
6.常用函数式接口(predicate接口)
有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用 java.util.function.predicate<t> 接口
6.1, test方法  
predicate 接口中包含一个抽象方法:boolean test(t t) 。用于条件判断的场景
1.public enum singleclass06 {  
2.    instance;  
3.}
6.2,基本使用
1.public static void main(string[] args) {  
2.    system.out.println(predicatetest((msg) -> msg.length() > 3, "hello"));  
3.}  
4.  
5.  
6.public static boolean predicatetest(predicate<string> predicate,string msg){  
7.    return predicate.test(msg);  
8.      
9.} 
7.总结
在本文中,我们学会了使用lambda表达式的不同方式,同时也学习了java8.0开始自带的一些常用函数式接口。

深圳分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录