Java8的Lambda-表达式

10次阅读

共计 1884 个字符,预计需要花费 5 分钟才能阅读完成。

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 表达式可以看做是一个方法,我们把这个方法直接可以传递到另一个方法中。

正文完
 0