Java Lambda 表达式概念

假设一个情景: 找出满足条件的Hero

从使用普通方法,匿名类,以及Lambda这几种方式,逐渐的引入Lambda的概念

步骤 1 : 普通方法

使用一个普通方法,在for循环遍历中进行条件判断,筛选出满足条件的数据

hp>100 && damage<50

package lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Random; import charactor.Hero; public class TestLambda {
public static void main(String[] args) {
Random r = new Random();
List<Hero> heros = new ArrayList<Hero>();
for (int i = 0; i < 10; i++) {
heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
}
System.out.println("初始化后的集合:");
System.out.println(heros);
System.out.println("筛选出 hp>100 && damange<50的英雄");
filter(heros);
} private static void filter(List<Hero> heros) {
for (Hero hero : heros) {
if(hero.hp>100 && hero.damage<50)
System.out.print(hero);
}
} }
package charactor; public class Hero implements Comparable<Hero>{
public String name;
public float hp; public int damage; public Hero(){ } public Hero(String name) {
this.name =name; } //初始化name,hp,damage的构造方法
public Hero(String name,float hp, int damage) {
this.name =name;
this.hp = hp;
this.damage = damage;
} @Override
public int compareTo(Hero anotherHero) {
if(damage<anotherHero.damage)
return 1;
else
return -1;
} @Override
public String toString() {
return "Hero [name=" + name + ", hp=" + hp + ", damage=" + damage + "]\r\n";
} }

步骤 2 : 匿名类方式

首先准备一个接口HeroChecker,提供一个test(Hero)方法

然后通过匿名类的方式,实现这个接口

HeroChecker checker = new HeroChecker() {
public boolean test(Hero h) {
return (h.hp>100 && h.damage<50);
}
};

接着调用filter,传递这个checker进去进行判断,这种方式就很像通过Collections.sort在对一个Hero集合排序,需要传一个Comparator的匿名类对象进去一样。

package lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Random; import charactor.Hero; public class TestLambda {
public static void main(String[] args) {
Random r = new Random();
List<Hero> heros = new ArrayList<Hero>();
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
}
System.out.println("初始化后的集合:");
System.out.println(heros);
System.out.println("使用匿名类的方式,筛选出 hp>100 && damange<50的英雄");
HeroChecker checker = new HeroChecker() {
@Override
public boolean test(Hero h) {
return (h.hp>100 && h.damage<50);
}
}; filter(heros,checker);
} private static void filter(List<Hero> heros,HeroChecker checker) {
for (Hero hero : heros) {
if(checker.test(hero))
System.out.print(hero);
}
} }
package lambda; import charactor.Hero; public interface HeroChecker {
public boolean test(Hero h);
}

步骤 3 : Lambda方式

使用Lambda方式筛选出数据

filter(heros,(h)->h.hp>100 && h.damage<50);

同样是调用filter方法,从上一步的传递匿名类对象,变成了传递一个Lambda表达式进去

h->h.hp>100 && h.damage<50

乍一看Lambda表达式似乎不好理解,其实很简单,下一步讲如何从一个匿名类一点点演变成Lambda表达式

package lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Random; import charactor.Hero; public class TestLamdba {
public static void main(String[] args) {
Random r = new Random();
List<Hero> heros = new ArrayList<Hero>();
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
}
System.out.println("初始化后的集合:");
System.out.println(heros);
System.out.println("使用Lamdba的方式,筛选出 hp>100 && damange<50的英雄");
filter(heros,h->h.hp>100 && h.damage<50);
} private static void filter(List<Hero> heros,HeroChecker checker) {
for (Hero hero : heros) {
if(checker.test(hero))
System.out.print(hero);
}
} }

步骤 4 : 设置eclipse以支持Lambda

如果你的eclipse能够正常识别Lambda,那么就可以跳过这个章节了。

因为Lambda是JDK8的内容,除了JDK需要使用1.8以上版本外(在JDK环境变量配置下载的就是1.8了),还需要在eclipse中把编译器设置为1.8才能够正常识别Lambda.

设置办法:

菜单->Window->Preferences->Java-Compiler->Compiler compliance leve: 设置为1.8即可



步骤 5 : 从匿名类演变成Lambda表达式

Lambda表达式可以看成是匿名类一点点演变过来

  1. 匿名类的正常写法

    HeroChecker c1 = new HeroChecker() {

    public boolean test(Hero h) {

    return (h.hp>100 && h.damage<50);

    }

    };

  2. 把外面的壳子去掉

    只保留方法参数方法体

    参数和方法体之间加上符号 ->

    HeroChecker c2 = (Hero h) ->{

    return h.hp>100 && h.damage<50;

    };

  3. 把return和{}去掉

    HeroChecker c3 = (Hero h) ->h.hp>100 && h.damage<50;

  4. 把 参数类型和圆括号去掉(只有一个参数的时候,才可以去掉圆括号)

    HeroChecker c4 = h ->h.hp>100 && h.damage<50;

  5. 把c4作为参数传递进去

    filter(heros,c4);

  6. 直接把表达式传递进去

    filter(heros, h -> h.hp > 100 && h.damage < 50);

     package lambda;
    
     import java.util.ArrayList;
    import java.util.List;
    import java.util.Random; import charactor.Hero; public class TestLamdba {
    public static void main(String[] args) {
    Random r = new Random();
    List<Hero> heros = new ArrayList<Hero>();
    for (int i = 0; i < 5; i++) {
    heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
    }
    System.out.println("初始化后的集合:");
    System.out.println(heros);
    System.out.println("使用匿名类的方式,筛选出 hp>100 && damange<50的英雄");
    // 匿名类的正常写法
    HeroChecker c1 = new HeroChecker() {
    @Override
    public boolean test(Hero h) {
    return (h.hp > 100 && h.damage < 50);
    }
    };
    // 把new HeroChcekcer,方法名,方法返回类型信息去掉
    // 只保留方法参数和方法体
    // 参数和方法体之间加上符号 ->
    HeroChecker c2 = (Hero h) -> {
    return h.hp > 100 && h.damage < 50;
    }; // 把return和{}去掉
    HeroChecker c3 = (Hero h) -> h.hp > 100 && h.damage < 50; // 把 参数类型和圆括号去掉
    HeroChecker c4 = h -> h.hp > 100 && h.damage < 50; // 把c4作为参数传递进去
    filter(heros, c4); // 直接把表达式传递进去
    filter(heros, h -> h.hp > 100 && h.damage < 50);
    } private static void filter(List<Hero> heros, HeroChecker checker) {
    for (Hero hero : heros) {
    if (checker.test(hero))
    System.out.print(hero);
    }
    }
    }

步骤 6 : 匿名方法

与匿名类 概念相比较,

Lambda 其实就是匿名方法,这是一种把方法作为参数进行传递的编程思想。

虽然代码是这么写

filter(heros, h -> h.hp > 100 && h.damage < 50);

但是,Java会在背后,悄悄的,把这些都还原成匿名类方式。

引入Lambda表达式,会使得代码更加紧凑,而不是各种接口和匿名类到处飞。

步骤 7 : Lambda的弊端

Lambda表达式虽然带来了代码的简洁,但是也有其局限性。

  1. 可读性差,与啰嗦的但是清晰的匿名类代码结构比较起来,Lambda表达式一旦变得比较长,就难以理解
  2. 不便于调试,很难在Lambda表达式中增加调试信息,比如日志
  3. 版本支持,Lambda表达式在JDK8版本中才开始支持,如果系统使用的是以前的版本,考虑系统的稳定性等原因,而不愿意升级,那么就无法使用。

Lambda比较适合用在简短的业务代码中,并不适合用在复杂的系统中,会加大维护成本。

Java自学-Lambda 概念的更多相关文章

  1. Java自学-Lambda 聚合操作

    java 集合的聚合操作 步骤 1 : 传统方式与聚合操作方式遍历数据 遍历数据的传统方式就是使用for循环,然后条件判断,最后打印出满足条件的数据 for (Hero h : heros) { if ...

  2. Java自学-Lambda 方法引用

    Lambda 方法引用 步骤 1 : 引用静态方法 首先为TestLambda添加一个静态方法: public static boolean testHero(Hero h) { return h.h ...

  3. 大学四年,总结一套适合小白的Java自学路线和方法

    前言篇 大家好,我是bigsai 好久不见,甚是想念,文章同时收录在回车课堂(文底阅读原文可达). 无论你是大学生还是在职人员,想学Java时,都会面临两个选择,自学或者报班.报班通常太费钱,时间又不 ...

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

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

  5. 【转】JAVA自学之路

    JAVA自学之路 一: 学会选择 为了就业,不少同学参加各种各样的培训. 决心做软件的,大多数人选的是java,或是.net,也有一些选择了手机.嵌入式.游戏.3G.测试等. 那么究竟应该选择什么方向 ...

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

    以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...

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

    以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...

  8. 深入浅出 Java 8 Lambda 表达式

    摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...

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

    PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...

随机推荐

  1. #《Essential C++》读书笔记# 第四章 基于对象的编程风格

    基础知识 Class的定义由两部分组成:class的声明,以及紧接在声明之后的主体.主体部分由一对大括号括住,并以分号结尾.主体内的两个关键字public和private,用来标示每个块的" ...

  2. python学习----文件的操作(2)

    1.文件指针的操作 f=open("yesterday","r",encoding="utf-8") #文件句柄 #文件内指针的操作 pri ...

  3. 浅谈Javascript中的原型、原型链、继承

    构造函数,原型,实例三者的关系 构造函数: 构造函数是创建对象的一种常用方式, 其他创建对象的方式还包括工厂模式, 原型模式, 对象字面量等.我们来看一个简单的构造函数: function Produ ...

  4. Eclipse中Git图标表示内容

    Eclipse中->属性->Team->Git->Label Decorations

  5. Elasticsearch必知必会的干货知识一:ES索引文档的CRUD

    ​ 若在传统DBMS 关系型数据库中查询海量数据,特别是模糊查询,一般我们都是使用like %查询的值%,但这样会导致无法应用索引,从而形成全表扫描效率低下,即使是在有索引的字段精确值查找,面对海量数 ...

  6. Debian 10 xfce 错误提示 ACCESS DENIED

    闲来无事重新安装自己的服务器发现很多关于Debian的初始安装问题都已经陌生了在此重新整理下自己安装所遇到的问题: ACCESS DENIED  释: 登录成功拒绝Root密码访问 解决方法: loc ...

  7. CSS3结构类选择器补充

    :empty 没有子元素(包括文本节点)的元素 :not  否定选择器 <!DOCTYPE html> <html lang="en" manifest=&quo ...

  8. EPEL添加与删除

    EPEL简介 EPEL的全称叫 Extra Packages for Enterprise Linux,由Fedora社区打造,如它的全称,这是一个为红帽系列及衍生发行版如CentOS.Fedora提 ...

  9. JSP+Servlet+Ajax实现用户增删改查的例子

    一.数据库设计 用户表User 已有的测试数据 二.Java代码编写 Java EE的架构一般分为以下五层: ①.Domain ②.DAO ③.Service ④.Controller ⑤.View ...

  10. Linux_Centos7安装VNC实现远程桌面

    一.首先安装GNOME桌面 yum groupinstall -y "GNOME Desktop"# 安装完成后,修改默认启动方式为图形化界面systemctl set-defau ...