文章目录
Lambda
01 Hello Lambda
1.1 普通方法
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";
}
}
使用一个普通方法,在for循环遍历中进行条件判断,筛选出满足条件的数据。
public static void main(String[] args) {
// TODO Auto-generated method stub
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("filter方法筛选出hp>100 && damage<50的集合:");
System.out.println(filter(heros));
private static List<Hero> filter(List<Hero> heros){
List<Hero> filterHero=new ArrayList<>();
for(Hero h:heros) {
if(h.hp>100&&h.damage<50)
filterHero.add(h);
}
return filterHero;
}
1.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的匿名类对象进去一样。
public interface HeroChecker {
public boolean test(Hero h) ;
}
package lambda;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class TestLambda{
public static void main(String[] args) {
// TODO Auto-generated method stub
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("filter方法筛选出hp>100 && damage<50的集合:");
System.out.println(filter(heros));
HeroChecker heroChecker=new HeroChecker() {
@Override
public boolean test(Hero h) {
// TODO Auto-generated method stub
return (h.hp>100&&h.damage<50);
}
};
System.out.println("匿名类方法筛选出hp>100 && damage<50的集合:");
System.out.println(filter(heros,heroChecker));
}
private static List<Hero> filter(List<Hero> heros){
List<Hero> filterHero=new ArrayList<>();
for(Hero h:heros) {
if(h.hp>100&&h.damage<50)
filterHero.add(h);
}
return filterHero;
}
private static List<Hero> filter(List<Hero> heros,HeroChecker checker) {
List<Hero> filterHero=new ArrayList<>();
for(Hero h:heros) {
if(checker.test(h))
filterHero.add(h);
}
return filterHero;
}
}
1.3 Lambda表达式
使用Lambda方式筛选出数据
filter(heros,(h)->h.hp>100 && h.damage<50);
同样是调用filter方法,从上一步的传递匿名类对象,变成了传递一个Lambda表达式进去
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("使用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);
}
}
}
1.4 匿名类演变Lambda表达式
Lambda表达式可以看成是匿名类一点点演变过来
- 匿名类的正常写法
HeroChecker c1 = new HeroChecker() {
public boolean test(Hero h) {
return (h.hp>100 && h.damage<50);
}
};
- 把外面的壳子去掉
只保留方法参数和方法体
参数和方法体之间加上符号 ->
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);
1.5 匿名方法
与匿名类 概念相比较,
Lambda 其实就是匿名方法,这是一种把方法作为参数进行传递的编程思想。
虽然代码是这么写
filter(heros, h -> h.hp > 100 && h.damage < 50);
但是,Java会在背后,悄悄的,把这些都还原成匿名类方式。
引入Lambda表达式,会使得代码更加紧凑,而不是各种接口和匿名类到处飞。
1.6 Lambda弊端
Lambda表达式虽然带来了代码的简洁,但是也有其局限性。
- 可读性差,与啰嗦的但是清晰的匿名类代码结构比较起来,Lambda表达式一旦变得比较长,就难以理解
- 不便于调试,很难在Lambda表达式中增加调试信息,比如日志
- 版本支持,Lambda表达式在JDK8版本中才开始支持ÿ