zoukankan      html  css  js  c++  java
  • 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 }
    View Code

    接下来看一个例子:

    1 public interface Condition {
    2         boolean test (Person p);
    3 }
    View Code
     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 }
    View Code

    上面的例子很简单,就是创建一个接口,里面有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 }
    View Code

    在这个例子中,条件判断的实现,通过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     }
    View Code

    这样的话,接口虽然修改了,但是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     }
    View Code

    个人感受是,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 }
    View Code

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

    方法的引用

    例子如下:

     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 }
    View Code

     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);
    View Code

    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 }
    View Code

    Stream

     1 public class StreamExcample {
     2 
     3     public static void main(String[] args) {
     4 
     5         List<Person> list = Arrays.asList(
     6                 new Person ("Charles", "Dickens", 60),
     7                 new Person ("Lewis", "Carrol", 42),
     8                 new Person ("Thamos", "Cayloe", 51),
     9                 new Person ("Charlotte", "Brote", 45),
    10                 new Person ("Matthew", "Aroid", 39)
    11                 );
    12         
    13         System.out.println("-------------------------");
    14         list.stream()
    15         .filter(p -> p.getLastName().startsWith("C"))
    16         .forEach(p -> System.out.println(p));
    17         System.out.println("-------------------------");
    18         long count = list.stream()
    19         .filter(p -> p.getFirstName().startsWith("M"))
    20         .count();
    21         System.out.println(count);
    22     }
    23 }
    24 
    25 
    26 -------------------------
    27 firstName :Lewis lastName :Carrol age 42
    28 firstName :Thamos lastName :Cayloe age 51
    29 -------------------------
    30 1
    View Code

    里面的Stream等一些8中新出现的东西还是蛮有趣的,以后编码时会尝试使用,棒棒的!

    推荐看篇头推荐的那个youbute的链接视频,very excellent for tutorials of Lambda

  • 相关阅读:
    [CareerCup] 11.6 Search a 2D Matrix 搜索一个二维矩阵
    [CareerCup] 11.5 Search Array with Empty Strings 搜索含有空字符串的数组
    [CareerCup] 11.4 Sort the File 文件排序
    [CareerCup] 11.3 Search in Rotated Sorted Array 在旋转有序矩阵中搜索
    VTK 6.3.0 Qt 5.4 MinGW 4.9.1 Configuration 配置
    [CareerCup] 11.2 Sort Anagrams Array 异位词数组排序
    [CareerCup] 11.1 Merge Arrays 合并数组
    Matlab Delete Row or Col 删除矩阵的行或列
    [CareerCup] 10.7 Simplified Search Engine 简单的搜索引擎
    [LeetCode] Nim Game 尼姆游戏
  • 原文地址:https://www.cnblogs.com/lihao007/p/7545140.html
Copyright © 2011-2022 走看看