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

 
 
原文地址:https://www.cnblogs.com/ttylinux/p/4664247.html