Lambda

作者: ticktackdong | 来源:发表于2018-05-21 22:33 被阅读0次

    A.Hello 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)
    

    二.匿名方法

    与匿名类概念比较,Lambda其实就是匿名方法
    这是一种把方法作为参数传递的编程思想
    虽然代码是这么写的
     filter(heros,h->h.hp>100 && h.damage<50)
    但是Java会在背后悄悄地把这些都还原成匿名类方式
    引入Lambda表达式会使代码更加紧凑而不是各种接口和匿名类到处飞
    弊端:
      可读性差,一旦变得比较长就难以理解
      不便于调试,很难在表达式中增加调试信息
      版本支持,JDK8以后支持
    

    B.方法引用

    1.引用静态方法
       首先为TestLambda添加一个静态方法
         public static boolean testHero(Hero h){
                  return h.hp>100 && h.damage<50;
         }
         Lambda表达式中调用这个静态方法
             filter(heros,h->TestLambda.testHero(h));
             filter(heros,TestLambda::testHero);//写法二
    
    2.引用对象方法
       与引用静态方法很类似,只是传递方法的时候需要一个对象的存在
       TestLambda testLambda = new TestLambda();
       filter(heros, testLambda::testHero);
    
    3.引用容器中的方法
        首先为Hero添加一个方法
        public boolean matched(){
             return this.hp>100 && this.damage<50; 
       }
      filter(heros,h->h.matched());
      filter(heros,Herp::matched);//写法二
    
    4.引用构造器
       有的接口中的方法会返回一个对象,比如java.util.function.Supplier提供了一个get方法,返回一个对象
     public interface Supplier<T>{
        T get();
     }
       设计一个方法,参数是这个接口
     public static List getList(Supplier<List> s){
           return s.get();
      } 
      为了调用这个方法有三种方式
       1.匿名类
            Supplier<List> s = new Supplier<List>(){
               public List get(){
                    return new ArrayList();
                   }        
               }
             List list1 = getList(s);
       2.Lambda表达式
          List list2 = getList(()->new ArrayList());
       3.引用构造器
          List list3 = getList(ArrayList::new);
    

    C.聚合操作

    1.Stream和管道的概念
     heros
       .stream()
       .filter(h -> h.hp > 100 && h.damage < 50)
       .forEach(h -> System.out.println(h.name));
    Stream和Collection结构化的数据不一样, 
    Stream是一系列的元素,就像生产线上的罐头一样,一串串的出来
    管道是一系列的聚和操作又分为3部分
          管道源:
          中间操作:每个中间操作又会返回一个Stream。
                  中间操作是懒操作,并不会进行真正的便利
          结束操作:是流的最后一个操作,当这个操作被执行完后流就被用光了,无法再被操作。
                  不会返回Stream,但是会返回int,float,String,Collection或者什么都不返回。
                  结束操作才进行真正的遍历,在遍历的时候才会去进行中间操作的相关判断
    
    2.管道源
      把Collection切换成管道源很简单,调用stream()就行了
     heros.stream()
     但是数组却没有stream()方法,需要使用
       Arrays.stream(hs)或者Stream.of(hs)   
    
    3.中间操作
     主要分为两类,对元素进行筛选和转换成其他形式的流
     对元素进行筛选:
         filter  匹配
         distinct 去除重复(根据equals判断)
         sorted 自然排序
         sorted(Comparator<T>) 指定排序
         limit 保留
         skip 忽略
    转换为其他形式的流
        mapToDouble  转换成double的流
        map   转换成任意类型的流
    
    4.结束操作
       常见结束操作如下:
          forEach() 遍历每个元素
          toArray() 转换为数组
          min(Comparator<T>) 取最小的元素
          max(Comparator<T>) 取最大的元素
          count() 总数
          findFirst() 第一个元素

    相关文章

      网友评论

          本文标题:Lambda

          本文链接:https://www.haomeiwen.com/subject/xopqjftx.html