• 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

    普通方法

    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 + "] ";

        }

           

    }

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

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

    设置eclipse以支持Lambda

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


    更多内容,点击了解: https://how2j.cn/k/lambda/lambda-lamdba-tutorials/697.html

  • 相关阅读:
    数组与集合互转
    复选框 查看详情
    SQL Server 查询表备注信息的语句
    MSSql Server 索引'uq_f_userName' 依赖于 列'f_userName'。由于一个或多个对象访问此列,ALTER TABLE ALTER COLUMN f_userName 失败
    玄鸟
    Window Server 2012 R2 下 IE11 浏览器 无法安装Flash 怎么解决
    Window Server 2012 R2 没有照片查看器 打开图片都是画板问题怎么解决
    君子偕老
    燕燕
    羔羊
  • 原文地址:https://www.cnblogs.com/Lanht/p/12615481.html
Copyright © 2020-2023  润新知