Java 8 Lambda

最近查找资料学习时,发现例子中有好多地方用到了lambda表达式,所以今天学习记录一下。

推荐一个youtube的视频,讲解的非常不错。国内的伙伴有可能需要fan qiang才能看到。Good luck!!!

https://www.youtube.com/watch?v=gpIUfj3KaOc&list=PLqq-6Pq4lTTa9YGfyhyW2CqdtW9RtY-I3&index=1

Lambda表达式

它可以看做是函数型编程,那么java中函数定义就用接口来担当,所以,用到Lambda的时候需要使用一个接口。Lambda相关的语法规则也在下面代码中补充。

 1 public class LamdbaDemo01 {
 2
 3     public static void main(String[] args) {
 4
 5         // new Thread( () -> System.out.println("--")).start();
 6         MyLambda greet = () -> System.out.println("Hello World!");
 7         greet.foo();
 8         // MyAdd myAdd = (int i, int j) -> i + j;
 9         // 因为参数的变量名称一致,所以参数的变量类型可以省略
10         MyAdd myAdd = (i, j) -> i + j;
11         System.out.println(myAdd.add(2, 3));
12
13         // 当参数只有一个的时候可以省略() , 此外当箭头右侧的代码只用一行的时候,可以省略{}
14         MyLength myLength = s -> s.length();
15         System.out.println(myLength.leng("Hello world!"));
16     }
17 }
18
19 // 接口中只能有一个方法,这是使用Lambda表达式的要求
20 interface MyLambda {
21     void foo();
22 }
23
24 interface MyAdd {
25     int add(int i, int b);
26 }
27
28 interface MyLength {
29     int leng(String s);
30 }

接下来看一个例子:

1 public interface Condition {
2         boolean test (Person p);
3 }

 1 import java.util.Arrays;
 2 import java.util.Collections;
 3 import java.util.Comparator;
 4 import java.util.List;
 5
 6 public class Unit1ExercistWithJava7 {
 7
 8     public static void main(String args[]) {
 9
10     List<Person> list = Arrays.asList(
11             new Person ("Charles", "Dickens", 60),
12             new Person ("Lewis", "Carrol", 42),
13             new Person ("Thamos", "Cayloe", 51),
14             new Person ("Charlotte", "Brote", 45),
15             new Person ("Matthew", "Aroid", 39)
16             );
17
18     // step 1: sort list by lastName
19     Collections.sort(list, new Comparator<Person>(){
20         @Override
21         public int compare(Person o1, Person o2) {
22             return o1.getLastName().compareTo(o2.getLastName());
23         }
24     } );
25
26     // step 2: Create a method that print all elements in the list
27     printConditionally (list, new Condition(){
28         @Override
29         public boolean test(Person p) {
30             return true;
31         }
32     });
33
34     System.out.println("-------------------------");
35     // step 3: Create a method that prints all people whose lastName beginning whie C
36     printConditionally(list, new Condition(){
37         @Override
38         public boolean test(Person p) {
39             return p.getLastName().startsWith("C");
40         }
41     });
42     }
43
44     private static void printConditionally (List<Person> list, Condition condition) {
45         for (Person p : list) {
46             if (condition.test(p)) {
47                 System.out.println(p);
48             }
49         }
50     }
51 }

上面的例子很简单,就是创建一个接口,里面有test方法,之后创建了一个List,根据自己的需要将list中满足一定条件的值取出。这里例子是用Java7写的。

接下来看Lambda表达式的例子:

 1 import java.util.Arrays;
 2 import java.util.Collections;
 3 import java.util.List;
 4
 5 public class Unit1ExercistWithLambda {
 6
 7     public static void main(String args[]) {
 8
 9     List<Person> list = Arrays.asList(
10             new Person ("Charles", "Dickens", 60),
11             new Person ("Lewis", "Carrol", 42),
12             new Person ("Thamos", "Cayloe", 51),
13             new Person ("Charlotte", "Brote", 45),
14             new Person ("Matthew", "Aroid", 39)
15             );
16
17     // step 1: sort list by lastName
18     // 使用Lambda表达式时,刚开始写不出,可以先写出匿名类的形式,之后在这个基础上再进行修改,慢慢的就会写了
19     // 为什么括号里直接省略掉参数类型,你尅看用Java8实现的例子
20     Collections.sort(list, (p1, p2) -> p1.getLastName().compareTo(p2.getLastName()));
21
22     // step 2: Create a method that print all elements in the list
23     printConditionally (list, (p) -> true);
24
25     System.out.println("-------------------------");
26     // step 3: Create a method that prints all people whose lastName beginning whie C
27     printConditionally(list, (p) -> p.getLastName().startsWith("C"));
28     }
29
30     private static void printConditionally (List<Person> list, Condition condition) {
31         for (Person p : list) {
32             if (condition.test(p)) {
33                 System.out.println(p);
34             }
35         }
36     }
37 }

在这个例子中,条件判断的实现,通过Lambda表达式来实现,可以看到代码量的减少,这是它的一个好处。

我们现在思考一下使用Lambda表达式的步骤。首先需要有个接口,接口中,必须有且只有一个方法,这是使用Lambda的前提条件。

之后,你就可以编写接口的实现部分。

其实我们也可以不自己创建接口,使用java.util.function 包 里面存在的接口。

比如上面Lambda表达式的例子可以修改成如下:

1 private static void printConditionally (List<Person> list, Predicate<Person> predict) {
2         for (Person p : list) {
3             if (predict.test(p)) {
4                 System.out.println(p);
5             }
6         }
7     }

这样的话,接口虽然修改了,但是Lambda实现的部分,完全不用任何修改,这是Lambda的另一个优势。

我们还在可以在printConditionally方法中再添加一个功能接口,例子如下:

 1     // step 2: Create a method that print all elements in the list
 2     printConditionally (list, (p) -> true, (p) -> System.out.println(p));
 3
 4     System.out.println("-------------------------");
 5     // step 3: Create a method that prints all people whose lastName beginning whie C
 6     printConditionally(list, (p) -> p.getLastName().startsWith("C"), (p) -> System.out.println(p));
 7     }
 8
 9     private static void printConditionally (List<Person> list, Predicate<Person> predict, Consumer<Person> consumer) {
10         for (Person p : list) {
11             if (predict.test(p)) {
12                 consumer.accept(p);
13             }
14         }
15     }

个人感受是,Lambda表达式使代码解耦,提高结构的灵活性。

Exception的捕获

无例子不说话:

 1 import java.util.function.BiConsumer;
 2
 3 public class Unit1ExercistWithLambdaWithException {
 4
 5     public static void main(String args[]) {
 6         int [] someNumbers = {1,2,3,4};
 7         int key = 0;
 8         /*第二种设想是在 process 方法中的第三个参数外侧添加try catch
 9         但是那样的话,跟java 7的匿名类有些相似,而且,又会增加耦合度。
10         最后,使用现在的,第三种方式来捕获异常。可能会觉得麻烦,跟之前的两种方法没什么区别,
11         但是第三种方式,我觉得有些像AOP,而且这样对结构的入侵要少*/
12         process (someNumbers, key, wrapperLambda((k ,v) -> System.out.println(k/v)));
13     }
14
15     private static BiConsumer<Integer, Integer> wrapperLambda(BiConsumer<Integer, Integer> wrapper) {
16         return (k ,v) -> {
17             try {
18                 wrapper.accept(k, v);
19             } catch (ArithmeticException e) {
20                 System.out.println("Exception caught in wrapper lambda");
21             }
22         };
23     }
24
25     private static void process(int[] someNumbers, int key, BiConsumer<Integer, Integer> consumer) {
26         // Exception的捕捉的第一种设想是在下面代码块的外侧追加try catch 来捕捉异常
27         // 但是,这只是个抽象的process的方法,不能确定实现类中出现的异常,所以在这里捕捉,不合理
28         for (int i : someNumbers) {
29             consumer.accept(i, key);
30         }
31     }
32 }

不知道怎么该如何讲述这个部分,例子有注释,大家不懂的地方,再留言谈论。

方法的引用

例子如下:

 1 public class MethodReference {
 2
 3     public static void main(String[] args) {
 4
 5         // 下面两行的代码是等价的
 6         // Thread thread = new Thread(() -> printMessage());
 7         Thread thread = new Thread(MethodReference::printMessage);
 8         thread.start();
 9     }
10
11     private static void printMessage() {
12         System.out.println("Hello World!");
13     }
14
15 }

Unit1ExercistWithLambda3.java 中的例子中的部分代码:

1 // printConditionally(list, (p) -> p.getLastName().startsWith("C"), (p) -> System.out.println(p));
2
3     printConditionally(list, (p) -> p.getLastName().startsWith("C"), System.out::println);

foreach

 1 import java.util.Arrays;
 2 import java.util.List;
 3
 4 public class CollectionIterationExample {
 5
 6     public static void main(String[] args) {
 7         List<Person> list = Arrays.asList(
 8                 new Person ("Charles", "Dickens", 60),
 9                 new Person ("Lewis", "Carrol", 42),
10                 new Person ("Thamos", "Cayloe", 51),
11                 new Person ("Charlotte", "Brote", 45),
12                 new Person ("Matthew", "Aroid", 39)
13                 );
14
15         System.out.println("Using for loop");
16         for (int i=0; i<list.size();i++) {
17             System.out.println(list.get(i));
18         }
19
20         System.out.println("Using for each loop");
21         for (Person person : list) {
22             System.out.println(person);
23         }
24
25         // Java8 Lambda
26         System.out.println("Using for loop");
27         list.forEach(p -> System.out.println(p));
28         System.out.println("--------------");
29         list.forEach(System.out::println);
30     }
31
32 }

觉得Lambda的表达式非常便捷。

时间: 2024-10-07 13:36:57

Java 8 Lambda的相关文章

[Java 8 Lambda] java.util.stream 简介

包结构如下所示: 这个包的结构很简单,类型也不多. BaseStream接口 所有Stream接口类型的父接口,它继承自AutoClosable接口,定义了一些所有Stream都具备的行为. 因为继承自AutoClosable接口,所以所有的Stream类型都可以用在Java 7中引入的try-with-resource机制中,以达到自动关闭资源的目的.实际上,只有当Stream是通过Socket,Files IO等方式创建的时候,才需要关闭它.对于来自于Collections,Arrays的S

Java 8 lambda表达式示例

例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runnable实现方法,需要4行代码,而使用lambda表达式只需要一行代码.我们在这里做了什么呢?那就是用() -> {}代码块替代了整个匿名类. 1 // Java 8之前: 2 new Thread(new Runnable() { 3 @Override 4 public void run() {

深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)

转:http://zh.lucida.me/blog/java-8-lambdas-inside-out-library-features/ 关于 深入理解 Java 8 Lambda(语言篇--lambda,方法引用,目标类型和默认方法) 深入理解 Java 8 Lambda(类库篇--Streams API,Collector 和并行) 深入理解 Java 8 Lambda(原理篇--Java 编译器如何处理 lambda) 本文是深入理解 Java 8 Lambda 系列的第二篇,主要介绍

深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

最近看了一下java 8的一些新特性,其中最重要的莫过于Lambda表达式了,通过一阵子的学习,原本准备自己写一篇博客的,后来阅读了一位学长翻译过来的博客(原文是Brain Goetz的State of Lambda,下面会给出原文链接),觉得写的十分完美,把我想要写的和我没想到的都罗列了出来,就把这个分享给大家了. 注:原译文见  http://lucida.me/blog/java-8-lambdas-insideout-language-features/ 英语原版见:http://cr.

用Java 8 Lambda表达式实现设计模式:命令模式

链接:http://www.importnew.com/16789.html 在这篇博客里,我将说明如何在使用Java 8 Lambda表达式的函数式编程方式时实现命令设计模式.命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化,并提供相应的操作.命令模式是一种通用编程方式,该方式基于运行时决策顺序来执行方法.模式的参与者如下: 命令 :声明用于执行操作的接口. 实体命令 :定义接收者对象和动作的绑定. 客户端 :创建实体命令实例并设置它的接收者. 调用者:

[转]深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)

以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-library-features 本文谢绝转载,如需转载需征得作者本人同意,谢谢. -------------------------------------内容分割线--------------------------------------------------------- 深入理解Java

[转]深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language-features 本文谢绝转载,如需转载需征得作者本人同意,谢谢. -------------------------------------内容分割线--------------------------------------------------------- 关于 本文是深入

Java 8 Lambda表达式10个示例【存】

PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是匿名类,需要6行代码.而定义行为最重要的那行代码,却混在中间不够突出.Lambda表达式取代了匿名类,取消了模板,允许用函数式风格编写代码.这样有时可读性更好,表达更清晰.在Java生态系统中,函数式表达与对面向对象的全面支持是个激动人心的进步.将进一步促进并行第三方库的发展,充分利用多核CPU.尽

[转载]深入理解Java 8 Lambda

原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language-features/ 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法) 2014年10月24日 | 评论 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://lucida.me/blog/java-8-lambdas-insideout-language-features/ 关于 深入理

Java 8 Lambda 揭秘

再了解了Java 8 Lambda的一些基本概念和应用后, 我们会有这样的一个问题: Lambda表达式被编译成了什么?. 这是一个有趣的问题,涉及到JDK的具体的实现. 本文将介绍OpenJDK对Lambda表达式的转换细节, 读者可以了解Java 8 Lambda表达式背景知识. Lambda表达式的转换策略 Brian Goetz是Oracle的Java语言架构师, JSR 335(Lambda Expression)规范的lead, 写了几篇Lambda设计方面的文章, 其中之一就是Tr