在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(); }
}
上述代码的含义是,创建两个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();
}
}
}
上述代码的含义,对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( "\n==== Test 03 ====");
System.out.println( "\n=== Calling all Drivers ===" );
robo.phoneContacts( pl,
new MyTest<Person>(){
@Override
public boolean test(Person p){
return p .getAge() >=16;
}
}
); System.out.println( "\n=== 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( "\n=== Mail all Pilots,Using Lambda Expression ===" );
robo.mailContacts( pl,( p)-> p.getAge() >= 23 && p.getAge() <= 65); }
}
上述代码做的事情,将一个列表中的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( "\n==== Test 04 ====");
System.out.println( "\n=== Calling all Drivers ===" );
robo.phoneContacts( pl, allDrivers); System.out.println( "\n=== Emailing all Draftees ===" );
robo.emailContacts( pl, allDraftees); System.out.println( "\n=== Mail all Pilots ===");
robo.mailContacts( pl, allPilots); // Mix and match becomes easy
System.out.println( "\n=== Mail all Draftees ===");
robo.mailContacts( pl, allDraftees); System.out.println( "\n=== Call all Pilots ===");
robo.phoneContacts( pl, allPilots); }
}
上述代码的含义,实现多个筛选操作,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( "\n==== 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 "\nName: " + p .getGivenName() + " " + p.getSurName() + "\n" +
"Age: " + p .getAge() + " " + "Gender: " + p .getGender() + "\n" +
"EMail: " + p .getEmail() + "\n" +
"Phone: " + p .getPhone() + "\n" +
"Address: " + p .getAddress();
}; Function<Person,String> easternStyle = new Function<Person,String>(){ @Override
public String apply(Person p )
{
return "\nName: " + p .getSurName() + " "
+ p.getGivenName() + "\n" + "Age: " + p .getAge() + " " +
"Gender: " + p .getGender() + "\n" +
"EMail: " + p .getEmail() + "\n" +
"Phone: " + p .getPhone() + "\n" +
"Address: " + p .getAddress();
} }; // Print Western List
System.out.println( "\n===Western List===");
for (Person person: list1){
System. out.println(
person. printCustom(westernStyle)
);
} // Print Eastern List
System.out.println( "\n===Eastern List===");
for (Person person: list1){
System. out.println(
person. printCustom(easternStyle)
);
} }
}
上述代码的含义,使用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();
}
}
上述代码含义,创建三个筛选条件,将筛选条件保存到一个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( "\n=== Western Pilot Phone List ===" ); pl.stream().filter(search .getCriteria("allPilots")).forEach(Person::printWesternName); System.out.println( "\n=== Eastern Draftee Phone List ===" ); pl.stream().filter(search .getCriteria("allDraftees")).forEach(Person::printEasternName);
//filter(Predicate<? super Person>)
//forEach(Consumer<? super Person>)
}
}

在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

 
 

lambda表达式的应用例子和JavaSE 8特性的更多相关文章

  1. Java lambda 表达式详解(JDK 8 新特性)

    什么是 lambda 表达式 lambda 表达式(拉姆达表达式)是 JAVA 8 中提供的一种新的特性,它使 Java 也能进行简单的"函数式编程". lambda 表达式的本质 ...

  2. Lambda 表达式的演示样例-来源(MSDN)

    本文演示怎样在你的程序中使用 lambda 表达式. 有关 lambda 表达式的概述.请參阅 C++ 中的 Lambda 表达式. 有关 lambda 表达式结构的具体信息,请參阅 Lambda 表 ...

  3. C++11里面的Lambda表达式

    Lambda Expressions in C++ C++中的Lambda表达式 In Visual C++, a lambda expression—referred to as a lambda— ...

  4. Java8(1)之Lambda表达式初步与函数式接口

    Lambda表达式初步 介绍 什么是Lambda表达式? 在如 Lisp.Python.Ruby 编程语言中,Lambda 是一个用于表示匿名函数或闭包的运算符 为何需要lambda表达式? 在 Ja ...

  5. lambda表达式底层处理机制

    为了支持函数式编程,Java 8引入了Lambda表达式,那么在Java 8中到底是如何实现Lambda表达式的呢? Lambda表达式经过编译之后,到底会生成什么东西呢? 在没有深入分析前,让我们先 ...

  6. lambda表达式/对象引用计数

    ★lambda表达式的用法例:I=[(lambda x: x*2),(lambda y: y*3)]调用:for x in I: print x(2)输出:4,6 ★获取对象的引用次数sys.getr ...

  7. Lambda 表达式的示例

    本文中的过程演示如何使用 lambda 表达式. 有关 lambda 表达式的概述,请参见 C++ 中的 Lambda 表达式. 有关 lambda 表达式结构的更多信息,请参见 Lambda 表达式 ...

  8. JAVA8初探-让方法参数具备行为能力并引入Lambda表达式

    关于JAVA8学习的意义先来贴一下某网站上的对它的简单介绍:“Java 8可谓Java语言历史上变化最大的一个版本,其承诺要调整Java编程向着函数式风格迈进,这有助于编写出更为简洁.表达力更强,并且 ...

  9. lambda函数、lambda表达式

    C++11 新特性:Lambda 表达式 豆子 2012年5月15日 C++ 10条评论 参考文章:https://blogs.oracle.com/pcarlini/entry/c_1x_tidbi ...

随机推荐

  1. iOS- 封装单例宏

    在项目中,我们需要全局只有一个实例,节省不必要的内存,这时我们就需要使用里单例生成对象. 这时把单例的代码封装成宏,就能方便我们下次使用了. 在.h .m里直接导入头文件,调用 传入类名即可! sin ...

  2. ubuntu软件管理apt与dpkg

    目前ubuntu系统主要有dpkg和apt两种软件管理方式两种区别如下 1.dpkg是用来安装.deb文件,但不会解决模块的依赖关系,且不会关心ubuntu的软件仓库内的软件,可以用于安装本地的deb ...

  3. dedecms添加新模型

    dedecms虽然预设了一些常见网页的功能模型,但是如果需要新的功能则需要自己创建,dedecms也提供了创建新模型的功能,如下: 1.打开后台首页=>核心=>内容模型管理 2.添加新模型 ...

  4. Java 8中 基本数据类型

    1)四种整数类型(byte.short.int.long):    byte:8 位,用于表示最小数据单位,如文件中数据,-128~127    short:16 位,很少用,-32768 ~ 327 ...

  5. 【.Net】C#文本文件(.txt)读写

    目录 前言 读取txt文件 写入txt文件 前言 计算机在最初只支持ASCII编码,但是后来为了支持其他语言中的字符(比如汉字)以及一些特殊字符(比如€),就引入了Unicode字符集.基于Unico ...

  6. Python 配置日志的几种方式

    Python配置日志的几种方式 作为开发者,我们可以通过以下3种方式来配置logging: (1)使用Python代码显式的创建loggers,handlers和formatters并分别调用它们的配 ...

  7. 配置bond和vlan

    网卡是光口还是电口的方法ethtool 网卡名字 一看速度二看port是否是firber首先查看需要做bond的物理网卡,如enp130s0f0,enp131s0f0以物理网卡为enp130s0f0, ...

  8. POJ3384:Feng Shui——题解

    http://poj.org/problem?id=3384 题目大意:给一个顺时针序的多边形,求在里面放半径为r的两个圆使得两圆覆盖的面积最大,求出这样的圆的坐标. ———————————————— ...

  9. C/C++中字符串与数字相互转换

    数字转字符串: 用C++的streanstream: #include <sstream> #Include <string> string num2str(double i) ...

  10. ExtJs在页面上window再调用Window的事件处理

    今天在开发Ext的过程中遇到了一个恶心的问题,就是在ext.window页面,点击再次弹出window时,gridpanel中的store数据加载异常,不能正常被加载,会出现缓存,出现该问题,是因为w ...