转载

Java8的Lambda 表达式

Java8的Lambda 表达式

Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。Lambda 表达式其实是一个匿名函数。

一、演变过程

1.普通方法的写法

定义一个Hero对象,存储英雄的属性

public class Hero implements Comparable<Hero> {
    /**
     * 英雄名
     */
    public String name;
    /**
     * 血量
     */
    public float hp;
    /**
     * 伤害
     */
    public int damage.......

筛选出,满足下面条件的英雄类

private static void filter(List<Hero> heros) {
    for (Hero hero : heros) {
        if (hero.hp > 100 && hero.damage < 50)
            System.out.print(hero);
    }
}

这种方式,如果筛选条件改变,需要重新再写一个方法,稍微麻烦一点。

2.匿名方法的写法

定义一个接口,接口的方法是判断是否满足的条件。

public interface IHeroChecker {
    /**
     * 判断Hero是否满足条件
     * @param h
     * @return
     */
    public boolean checker(Hero h);
}

写一个过滤方法,判断条件是调用IHeroChecker对象的checker方法,其实就是这个方法中要使用另一个类的方法。

private static void filter(List<Hero> heros,IHeroChecker checker) {
    for (Hero hero : heros) {
        if(checker.checker(hero))
        System.out.print(hero);
    }
}

//匿名类对实现此判断方法
IHeroChecker checker = new IHeroChecker() {
    @Override
    public boolean checker(Hero h) {
        return (h.hp>100 && h.damage<50);
    }
};
filter(heros,checker);

使用匿名类实现这个方法,再调用filter方法

3.Lambda 表达式的写法

使用Lambda 表达式就不用写匿名类了,将匿名类演变成Lambda表达式;

1.把匿名类外面的壳子去掉,只保留方法参数和方法体;

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

3.把return和{}去掉

4.只有一个参数时可以去掉();

//匿名类对实现此判断方法
IHeroChecker checker = new IHeroChecker() {
    @Override
    public boolean checker(Hero h) {
        return (h.hp>100 && h.damage<50);
    }
};

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

二、与匿名方法关系

与匿名类概念相比较,Lambda 其实就是匿名方法,这是一种把方法作为参数进行传递的编程思想。java执行时,还是会将他变成匿名类的.

三、Lambda表达式弊端

1.可读性差,匿名类代码结构比较起来,Lambda表达式一旦变得比较长,不好理解;

2.不便于调试,很难在Lambda表达式中增加调试信息;

3.版本支持,在JDK8以后才有,之前的版本不支持。

四、Lambda表达式方法的引用

前面我们讲了,Lambda表达式其实就是一个方法,把{}和return去掉了而已,那我们如果有现成的方法,用已有的方法代替它该怎么做

1.引用静态方法

已经有了静态方法

public static boolean checker(Hero h) {
    return h.hp>100 && h.damage<50;
}

在Lambda表达式中使用

filter(heros, h -> LambdaTest.checker(h) );

直接引用

filter(heros, LambdaTest::checker);

2.引用对象的方法

引用LambdaTest对象中testHero方法

LambdaTest lambdaTest = new LambdaTest();
filter(heros, lambdaTest::testHero);

3.引用容器对象的方法

在Hero对象中有

private boolean matched(){
    return (hp > 100 && damage < 50);
}

在Lambda表达式中使用

filter(heros, h -> h.matched());

直接引用

filter(heros, Hero::matched);

五、总结

可以认为Lambda表达式可以看做是一个方法,我们把这个方法直接可以传递到另一个方法中。

原文  https://segmentfault.com/a/1190000019523890
正文到此结束
Loading...