• lambda表达式的应用例子和JavaSE 8特性


    在JavaSE 8 引入了lambda表达式,lambda表达式的引入带来的好处是:通过语法上的改进,减少开发人员需要编写和维护的代码数量。这个在下面使用和不使用lambda的对比中可以清晰看出来。

    1.

    public class RunnableTest {
    
           
            public static void main(String[] args){
                  
                  System. out.println("===============RunnableTest=================" );
                  
                  
                   //Anonymous Runnable
                  Runnable r1 = new Runnable(){
                         
                          @Override
                          public void run(){
                               
                           System. out.println("Hello world, I am runnable one." );
                         }
                  };
                  
                  
                   //Lambda Runnable
                  Runnable r2 = ()->System. out.println("Hello world, I am runnable two");
                  
                   r1.run();
                   r2.run();
                  
           }
    }
    View Code
    上述代码的含义是,创建两个Runnable对象,然后运行它。r1是一个只有一个实现方法的匿名类,这种只有一个实现方法的接口,叫做功能性接口(Functional Interface)。
    r2,是使用一个lambda表达式,从这个声明语句:Runnable r2 = ()->System. out.println("Hello world, I am runnable two");可以看出,这个lambda表达式的类型是
    Runnable,也就是最终的结果类型是Runnable。
    2.
    public class ComparatorTest {
     
       public static void main(String[] args) {
       
         List<Person> personList = Person.createShortList();
      
         // Sort with Inner Class
         Collections.sort(personList , new Comparator<Person>(){
           public int compare(Person p1 , Person p2){
             return p1 .getSurName().compareTo(p2.getSurName());
           }
         });
         System.out.println( "=== Sorted Asc SurName ===");
         for(Person p: personList){
           p.printName();
         }
    
         // Use Lambda instead
        
         // Print Asc
         System.out.println( "=== Sorted Asc SurName ===");
         Collections.sort(personList , (Person p1, Person p2) -> p1.getSurName().compareTo(p2 .getSurName()));
     
         for(Person p: personList){
           p.printName();
         }
        
         // Print Desc
         System.out.println( "=== Sorted Desc SurName ===");
         Collections.sort(personList , (p1 ,  p2 ) -> p2.getSurName().compareTo(p1 .getSurName()));
     
         for(Person p: personList){
           p.printName();
         }
       }
    }
    View Code
    上述代码的含义,对personList进行排序。要对personList进行排序,就要实现一个Comparator接口,然后,使用Collections.sort(list, comparator)来实现排序。
    在第一部分,使用一个匿名类来实现Comparator接口。
    第二部分,使用一个lambda表达式来实现Comparator<Person>接口。lambda表达式(Person p1, Person p2) -> p1.getSurName().compareTo(p2 .getSurName())的类型是Comparator<Person>。这个lambda指明了参数的类型是Person,(Person p1,Person p2)。
    第三部分,也是使用lambda表达式来实现Comparator<Person>接口,(p1 ,  p2 ) -> p2.getSurName().compareTo(p1 .getSurName())。这次并没有指明参数类型(p1,p2)。因为Comparator<Person>是一个泛型,编译器在编译的时候,可以进行类型推断,推断出参数比较的参数类型是Person。
     
     
    =========================================================================================================================================================
    lambda表达式的语法:
        
     
    (int x, int y) -> x + y
    Argument List Arrow Token Body
                        一个lambda表达式被划分为三部分,从最左边开始,分别是参数列表,箭头符号,代码块。代码块,相当于一个方法的方法体,可以返回内容,也可以不返回内容。
     
    3.
    /**
     * @author MikeW
     */
    public interface MyTest<T> {
      public boolean test(T t );
    }
    
    
    /**
     *
     * @author MikeW
     */
    public class RoboContactAnon {
    
      public void phoneContacts(List<Person> pl , MyTest<Person> aTest){
        for(Person p: pl){
          if (aTest.test(p)){
            roboCall( p);
          }
        }
      }
    
      public void emailContacts(List<Person> pl , MyTest<Person> aTest){
        for(Person p: pl){
          if (aTest.test(p)){
            roboEmail( p);
          }
        }
      }
    
      public void mailContacts(List<Person> pl , MyTest<Person> aTest){
        for(Person p: pl){
          if (aTest.test(p)){
            roboMail( p);
          }
        }
      } 
     
      public void roboCall(Person p ){
        System.out.println( "Calling " + p .getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p .getPhone());
      }
     
      public void roboEmail(Person p ){
        System.out.println( "EMailing " + p .getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p .getEmail());
      }
     
      public void roboMail(Person p ){
        System.out.println( "Mailing " + p .getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p .getAddress());
      }
     
    }
    
    
    /**
     * @author MikeW
     */
    public class RoboCallTest03 {
    
      public static void main(String[] args) {
       
        List<Person> pl = Person. createShortList();
        RoboContactAnon robo = new RoboContactAnon();
       
        System.out.println( "
    ==== Test 03 ====");
        System.out.println( "
    === Calling all Drivers ===" );
        robo.phoneContacts( pl,
            new MyTest<Person>(){
              @Override
              public boolean test(Person p){
                return p .getAge() >=16;
              }
            }
        );
       
    
        System.out.println( "
    === Emailing all Draftees,Using Lambda Expression ===" );
        MyTest<Person> allDraftees = (p )->p .getAge() >= 18 && p.getAge() <= 25 && p.getGender() == Gender.MALE;
        robo.emailContacts( pl, allDraftees);
           
       
        System.out.println( "
    === Mail all Pilots,Using Lambda Expression ===" );
        robo.mailContacts( pl,( p)-> p.getAge() >= 23 && p.getAge() <= 65);
       
      
      }
    }
    View Code
    上述代码做的事情,将一个列表中的Person进行划分,按照不同的条件区分出不同的人群。将一个筛选操作抽象为MyTest<T>接口,让客户自己去实现。MyTest<T>是一个功能性接口,只有一个比较方法要实现。这里在实现MyTest<T>接口时,可以使用Lambda表达式。
     
     
     
    4. java.util.function.Predicate的应用
     
    JavaSE 8提供了一个java.util.function包,这个包提供了多个功能性接口(只有一个方法的接口)。
    java.util.function.Predicate这个接口,用来表示一个筛选,筛选某个具体的类型元素是否符合指定的条件。
    public interface Predicate<T> {
       public boolean test(T t);
     }
    /**
     *
     * @author MikeW
     */
    public class RoboContactLambda {
      public void phoneContacts(List<Person> pl , Predicate<Person> pred){
        for(Person p: pl){
          if (pred.test(p)){
            roboCall( p);
          }
        }
      }
    
      public void emailContacts(List<Person> pl , Predicate<Person> pred){
        for(Person p: pl){
          if (pred.test(p)){
            roboEmail( p);
          }
        }
      }
    
      public void mailContacts(List<Person> pl , Predicate<Person> pred){
        for(Person p: pl){
          if (pred.test(p)){
            roboMail( p);
          }
        }
      } 
     
      public void roboCall(Person p ){
        System.out.println( "Calling " + p .getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p .getPhone());
      }
     
      public void roboEmail(Person p ){
        System.out.println( "EMailing " + p .getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p .getEmail());
      }
     
      public void roboMail(Person p ){
        System.out.println( "Mailing " + p .getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p .getAddress());
      }
    
    }
    
    
    /**
     *
     * @author MikeW
     */
    public class RoboCallTest04 {
     
      public static void main(String[] args){
    
        List<Person> pl = Person. createShortList();
        RoboContactLambda robo = new RoboContactLambda();
       
        // Predicates
        Predicate <Person> allDrivers = p -> p .getAge() >= 16;
        Predicate <Person> allDraftees = p -> p .getAge() >= 18 && p.getAge() <= 25 && p.getGender() == Gender.MALE;
        Predicate<Person> allPilots = new Predicate<Person>(){
           
           @Override
           public boolean test(Person p )
           {
                  
                   return  p .getAge() >= 23 && p.getAge() <= 65;
           }
        };
        
       
        System.out.println( "
    ==== Test 04 ====");
        System.out.println( "
    === Calling all Drivers ===" );
        robo.phoneContacts( pl, allDrivers);
       
        System.out.println( "
    === Emailing all Draftees ===" );
        robo.emailContacts( pl, allDraftees);
       
        System.out.println( "
    === Mail all Pilots ===");
        robo.mailContacts( pl, allPilots);
       
        // Mix and match becomes easy
        System.out.println( "
    === Mail all Draftees ===");
        robo.mailContacts( pl, allDraftees); 
       
        System.out.println( "
    === Call all Pilots ===");
        robo.phoneContacts( pl, allPilots);   
       
      }
    }
    View Code
    上述代码的含义,实现多个筛选操作,allDrivers,allDraftees,allPilots代表具体的筛选条件。然后,传递筛选条件给对应的方法,从而从列表中取出想要的人群信息。每个筛选条件,都用lambda表达式表示。
        Predicate <Person> allDrivers = p -> p .getAge() >= 16;
        Predicate <Person> allDraftees = p -> p .getAge() >= 18 && p.getAge() <= 25 && p .getGender() == Gender. MALE;
        Predicate <Person> allPilots = p -> p .getAge() >= 23 && p.getAge() <= 65;
     
     
    5.java.util.function.Function的应用
    Function接口,
    Represents a function that accepts one argument and produces a result
     
    java.util.function.Function:
    public R apply(T t){ }
     
     
     
    Person:
     
      public String printCustom(Function <Person, String> f){
          return f.apply(this);
      }
     
    /**
     * @author MikeW
     */
    public class NameTestNew {
    
      public static void main(String[] args) {
       
        System.out.println( "
    ==== NameTestNew ===");
       
        List<Person> list1 = Person. createShortList();
       
        // Print Custom First Name and e-mail
        System.out.println( "===Custom List===");
        for (Person person: list1){
            System. out.println(
                person. printCustom(p -> "Name: " + p.getGivenName() + " EMail: " + p.getEmail())
            );
        }
    
       
        // Define Western and Eastern Lambdas
        Function<Person, String> westernStyle = p -> {
          return "
    Name: " + p .getGivenName() + " " + p.getSurName() + "
    " +
                 "Age: " + p .getAge() + "  " + "Gender: " + p .getGender() + "
    " +
                 "EMail: " + p .getEmail() + "
    " +
                 "Phone: " + p .getPhone() + "
    " +
                 "Address: " + p .getAddress();
        };
       
     
       Function<Person,String> easternStyle = new Function<Person,String>(){
             
            @Override
            public String apply(Person p )
            {
                   return  "
    Name: " + p .getSurName() + " "
                              + p.getGivenName() + "
    " + "Age: " + p .getAge() + "  " +
                              "Gender: " + p .getGender() + "
    " +
                              "EMail: " + p .getEmail() + "
    " +
                              "Phone: " + p .getPhone() + "
    " +
                              "Address: " + p .getAddress(); 
            }
             
       };
       
        // Print Western List
        System.out.println( "
    ===Western List===");
        for (Person person: list1){
            System. out.println(
                person. printCustom(westernStyle)
            );
        }
    
        // Print Eastern List
        System.out.println( "
    ===Eastern List===");
        for (Person person: list1){
            System. out.println(
                person. printCustom(easternStyle)
            );
        }
       
       
      }
    }
    View Code
    上述代码的含义,使用Function<T,R>接口,来表示要打印数据格式。有三种打印格式,Custom List, Western List, Eastern List。客户端根据自己的需要实现Function<T,R>接口,来获得相应的打印格式。
    第一部分,是直接使用lambda表达式 p -> "Name: " + p.getGivenName() + " EMail: " + p.getEmail(),该lambda表达式,在代码块中使用参数p打印输出。
    第二部分,也是使用lambda表达式,但是声明了表达式的类型是Function<Person,String>。
    第三部分,用一个匿名类实现Function<Person,String>接口。
     
     
     
     
    5.查询条件和Map结合结合
     
    为了重用筛选条件,我们可以把创建的筛选条件保存到Map中,在需要的时候,再通过一个Key来查找对应的筛选条件,这样就可以达到筛选条件重用。
    /**
     *
     * @author MikeW
     */
    public class SearchCriteria {
    
      private final Map<String, Predicate<Person>> searchMap = new HashMap<>();
    
      private SearchCriteria() {
        super();
        initSearchMap();
      }
    
      private void initSearchMap() {
        Predicate<Person> allDrivers = p -> p .getAge() >= 16;
        Predicate<Person> allDraftees = p -> p .getAge() >= 18 && p.getAge() <= 25 && p.getGender() == Gender.MALE;
        Predicate<Person> allPilots = p -> p .getAge() >= 23 && p.getAge() <= 65;
    
        searchMap.put( "allDrivers", allDrivers );
        searchMap.put( "allDraftees", allDraftees );
        searchMap.put( "allPilots", allPilots );
    
      }
    
      public Predicate<Person> getCriteria(String PredicateName) {
        Predicate<Person> target;
    
        target = searchMap.get( PredicateName);
    
        if (target == null) {
    
          System. out.println("Search Criteria not found... " );
          System.exit(1);
       
        }
         
        return target;
    
      }
    
      public static SearchCriteria getInstance() {
        return new SearchCriteria();
      }
    }
    View Code
    上述代码含义,创建三个筛选条件,将筛选条件保存到一个Map中。对外提供一个SearchCriteria实例,客户端通过getCriteria接口获取筛选条件。
     
     
     
    6.Java SE 8 集合对象的Stream和forEach功能
    /**
     *
     * @author MikeW
     */
    public class Test02Filter {
     
      public static void main(String[] args) {
    
        List<Person> pl = Person. createShortList();
       
        SearchCriteria search = SearchCriteria. getInstance();
       
        System.out.println( "
    === Western Pilot Phone List ===" );
    
        pl.stream().filter(search .getCriteria("allPilots")).forEach(Person::printWesternName);
       
      
        System.out.println( "
    === Eastern Draftee Phone List ===" );
    
        pl.stream().filter(search .getCriteria("allDraftees")).forEach(Person::printEasternName);
        //filter(Predicate<? super Person>)
       //forEach(Consumer<? super Person>)
      }
    }
    View Code

    在Java SE 8 中,集合对象有流,使用流中的方法filter,可以筛选出符合筛选条件的元素。

     参考资料:

    http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html

     https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

     
     
  • 相关阅读:
    ADO.net方法
    单例模式(Singleton)的6种实现
    小菜学习设计模式(五)—控制反转(Ioc)
    mysql及linux发行版下载源
    Linux应用总结(1):自动删除n天前日志
    linux挂载mount参数优化
    SQL Server Mysql primary key可更新性分析
    SQL Server 排名函数实现
    MySQL select
    MySQL 数据显示宽度
  • 原文地址:https://www.cnblogs.com/ttylinux/p/4664247.html
Copyright © 2020-2023  润新知