java lambda教程_Lambda系列教材 (一)- Java Lambda 表达式教程

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

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

步骤1:普通方法

步骤2:匿名类方式

步骤3:Lambda方式

步骤4:设置eclipse以支持Lambda

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

步骤6:匿名方法

步骤7:Lambda的弊端

步骤8:练习-Comparator

步骤9:答案-Comparator

步骤 1 : 普通方法

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

hp>100 && damage<50

aa112c9b98daca805260f74685f2e055.png

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 heros =new ArrayList();

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 heros) {

for (Hero hero : heros) {

if(hero.hp>100 && hero.damage<50)

System.out.print(hero);

}

}

}package charactor;

public class Heroimplements Comparable{

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

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的匿名类对象进去一样。

d753d8164a9a45ab0fa40f2f8aa6ae5e.png

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 heros =new ArrayList();

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 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表达式

d673bc01f4c0127001c3ccf7234ea6d5.png

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 heros =new ArrayList();

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 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即可

ae1337254c0692f311b1cdc0ab2f57e2.png

步骤 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 heros =new ArrayList();

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 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比较适合用在简短的业务代码中,并不适合用在复杂的系统中,会加大维护成本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值