zoukankan      html  css  js  c++  java
  • Java自学-Lambda 方法引用

    Lambda 方法引用

    步骤 1 : 引用静态方法

    首先为TestLambda添加一个静态方法:

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

    Lambda表达式:

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

    在Lambda表达式中调用这个静态方法:

    filter(heros, h -> TestLambda.testHero(h) );
    

    调用静态方法还可以改写为:

    filter(heros, TestLambda::testHero);
    

    这种方式就叫做引用静态方法

    引用静态方法

    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);
               
            HeroChecker c = new HeroChecker() {
                public boolean test(Hero h) {
                    return h.hp>100 && h.damage<50;
                }
            };
              
            System.out.println("使用匿名类过滤");
            filter(heros, c);
            System.out.println("使用Lambda表达式");
            filter(heros, h->h.hp>100 && h.damage<50);
            System.out.println("在Lambda表达式中使用静态方法");
            filter(heros, h -> TestLambda.testHero(h) );
            System.out.println("直接引用静态方法");
            filter(heros, TestLambda::testHero);
        }
           
        public static boolean testHero(Hero h) {
            return 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);
            }
        }
       
    }
    

    步骤 2 : 引用对象方法

    与引用静态方法很类似,只是传递方法的时候,需要一个对象的存在

    TestLambda testLambda = new TestLambda();
    filter(heros, testLambda::testHero);
    

    这种方式叫做引用对象方法

    引用对象方法

    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("使用引用对象方法  的过滤结果:");
            //使用类的对象方法
            TestLambda testLambda = new TestLambda();
            filter(heros, testLambda::testHero);
        }
         
        public boolean testHero(Hero h) {
            return 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);
            }
        }
     
    }
    

    步骤 3 : 引用容器中的对象的方法

    首先为Hero添加一个方法

    public boolean matched(){
       return this.hp>100 && this.damage<50;
    }
    

    使用Lambda表达式

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

    在Lambda表达式中调用容器中的对象Hero的方法matched

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

    matched恰好就是容器中的对象Hero的方法,那就可以进一步改写为

    filter(heros, Hero::matched);
    

    这种方式就叫做引用容器中的对象的方法

    引用容器中的对象的方法

    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("Lambda表达式:");       
            filter(heros,h-> h.hp>100 && h.damage<50 );
     
            System.out.println("Lambda表达式中调用容器中的对象的matched方法:");       
            filter(heros,h-> h.matched() );
      
            System.out.println("引用容器中对象的方法 之过滤结果:");       
            filter(heros, Hero::matched);
        }
           
        public boolean testHero(Hero h) {
            return 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 : 引用构造器

    有的接口中的方法会返回一个对象,比如java.util.function.Supplier提供
    了一个get方法,返回一个对象。

    public interface Supplier<T> {
        T get();
    }
    

    设计一个方法,参数是这个接口

    public static List getList(Supplier<List> s){
      return s.get();
    }
    

    为了调用这个方法,有3种方式
    第一种匿名类:

    Supplier<List> s = new Supplier<List>() {
        public List get() {
            return new ArrayList();
        }
    };
    List list1 = getList(s);
    

    第二种:Lambda表达式

    List list2 = getList(()->new ArrayList());
    

    第三种:引用构造器

    List list3 = getList(ArrayList::new);
    

    .

    package lambda;
     
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Supplier;
     
    public class TestLambda {
        public static void main(String[] args) {
        Supplier<List> s = new Supplier<List>() {
            public List get() {
                return new ArrayList();
            }
        };
     
        //匿名类
        List list1 = getList(s);
         
        //Lambda表达式
        List list2 = getList(()->new ArrayList());
         
        //引用构造器
        List list3 = getList(ArrayList::new);
     
        }
         
        public static List getList(Supplier<List> s){
            return s.get();
        }
          
    }
    

    练习引用构造器

    把比较ArrayList和LinkedList的区别这段代码,改造成引用构造器的模式。
    目前的调用方式是:

        List<Integer> l;
        l = new ArrayList<>();
        insertFirst(l, "ArrayList");
    
        l = new LinkedList<>();
        insertFirst(l, "LinkedList");
    

    改造后的调用方式将变为:

        insertFirst(ArrayList::new, "ArrayList");
        insertFirst(LinkedList::new, "LinkedList");
    
    package collection;
      
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
      
    public class TestCollection {
        public static void main(String[] args) {
            List<Integer> l;
            l = new ArrayList<>();
            insertFirst(l, "ArrayList");
      
            l = new LinkedList<>();
            insertFirst(l, "LinkedList");
      
        }
      
        private static void insertFirst(List<Integer> l, String type) {
            int total = 1000 * 100;
            final int number = 5;
            long start = System.currentTimeMillis();
            for (int i = 0; i < total; i++) {
                l.add(0, number);
            }
            long end = System.currentTimeMillis();
            System.out.printf("在%s 最前面插入%d条数据,总共耗时 %d 毫秒 %n", type, total, end - start);
        }
      
    }
    

    答案

    package collection;
       
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.function.Supplier;
       
    public class TestCollection {
        public static void main(String[] args) {
            insertFirst(ArrayList::new, "ArrayList");
            insertFirst(LinkedList::new, "LinkedList");
        }
       
        private static void insertFirst(Supplier<List> s, String type) {
            int total = 1000 * 100;
            final int number = 5;
            long start = System.currentTimeMillis();
            List list = s.get();
            for (int i = 0; i < total; i++) {
                list.add(0, number);
            }
            long end = System.currentTimeMillis();
            System.out.printf("在%s 最前面插入%d条数据,总共耗时 %d 毫秒 %n", type, total, end - start);
        }
       
    }
    
  • 相关阅读:
    Java的参数传递是值传递还是引用传递
    10张图带你深入理解Docker容器和镜像
    Java 如何有效地避免OOM:善于利用软引用和弱引用
    事务与一致性:刚性or柔性
    Java 面试题史上最强整理
    三张图秒懂Redis集群设计原理
    iOS开发笔记系列-基础4(变量与数据类型)
    iOS开发笔记系列-基础3(多态、动态类型和动态绑定)
    iOS开发笔记系列-基础2(类)
    iOS开发笔记系列-基础1(数据类型与表达式)
  • 原文地址:https://www.cnblogs.com/jeddzd/p/12336192.html
Copyright © 2011-2022 走看看