• [Java] Lambda表达式


    定义

    • 正常情况下,使用一个接口或抽象类,需要创建一个子类
    • 匿名类:实例化抽象类或接口后紧跟类定义(没有名字),从而使代码更加精简
    • 只有重写接口方法的一句话有用,其余的都可由编译器推断
    • Lambda方法:匿名方法,即把方法作为参数进行传递
    • Lambda表达式:应用在单一抽象方法接口(Single Abstract Method SAM)环境下的一种简化定义形式
    • 使用Lambda表达式必须具有接口,且接口中有且只有一个抽象方法
    • 使用Lambda表达式必须具有上下文推断,即方法的参数或局部变量类型必须为Lambda对应的接口类型,才可使用Lambda作为该接口的实例
    • Lambda表达式的内容不要超过三行
    • 有且只有一个抽象方法的接口,称为函数式接口
    • 实例化函数式接口主要是为了使用方法,即接口的实例化对象是只有函数的对象,故称函数对象
    • 演变过程(情景:找出满足要求的Hero)
      • 普通方法:定义判断方法,在for循环遍历中进行条件判断,筛选数据
      • 匿名类方法:定义接口,提供判断方法,通过匿名类实现,原判断方法接收判断对象和判断方法对象
      • Lambda表达式:简化匿名类的定义,只保留方法参数和方法体,中间加->
    • 基本语法
      • (参数) -> {方法体}
      • 只有一个参数,可以去掉()
      • 只有一行方法,可以去掉{} 

    匿名类

     1 import java.util.ArrayList;
     2 import java.util.List;
     3 import java.util.Random;
     4    
     5 import charactor.Hero;
     6    
     7 public class TestLambda {
     8     public static void main(String[] args) {
     9         Random r = new Random();
    10         List<Hero> heros = new ArrayList<Hero>();
    11         for (int i = 0; i < 5; i++) {
    12             heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
    13         }
    14         System.out.println("初始化后的集合:");
    15         System.out.println(heros);
    16         System.out.println("使用匿名类的方式,筛选出 hp>100 && damange<50的英雄");
    17         HeroChecker checker = new HeroChecker() {
    18             @Override
    19             public boolean test(Hero h) {
    20                 return (h.hp>100 && h.damage<50);
    21             }
    22         };
    23            
    24         filter(heros,checker);
    25     }
    26    
    27     private static void filter(List<Hero> heros,HeroChecker checker) {
    28         for (Hero hero : heros) {
    29             if(checker.test(hero))
    30                 System.out.print(hero);
    31         }
    32     }
    33 }
    View Code

    接口

    1 package lambda;
    2  
    3 import charactor.Hero;
    4  
    5 public interface HeroChecker {
    6     public boolean test(Hero h);
    7 }
    View Code

    Lambda表达式

     1 import java.util.ArrayList;
     2 import java.util.List;
     3 import java.util.Random;
     4  
     5 import charactor.Hero;
     6  
     7 public class TestLamdba {
     8     public static void main(String[] args) {
     9         Random r = new Random();
    10         List<Hero> heros = new ArrayList<Hero>();
    11         for (int i = 0; i < 5; i++) {
    12             heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
    13         }
    14         System.out.println("初始化后的集合:");
    15         System.out.println(heros);
    16         System.out.println("使用Lamdba的方式,筛选出 hp>100 && damange<50的英雄");
    17         filter(heros,h->h.hp>100 && h.damage<50);
    18     }
    19  
    20     private static void filter(List<Hero> heros,HeroChecker checker) {
    21         for (Hero hero : heros) {
    22             if(checker.test(hero))
    23                 System.out.print(hero);
    24         }
    25     }
    26  
    27 }
    View Code

    方法引用

    • 对象的引用传递可以实现不同的栈操作同一块堆内存空间
    • 技术早期阶段,希望针对于方法可以实现引用机制,在Spring框架中有相关功能
    • JDK 1.8后,方法也支持引用操作,相当于为方法定义了别名
    • 不再自己覆写接口,而是引用其他类中现成的方法实现接口,可节约代码量
    • 简化Lambda表达式在一些重复操作上的执行
    • 需要一个函数式接口,并设置好参数
    • 引用静态方法
      • 类名称 :: static 方法 ;
      • filter(heros, TestLambda::testHero);
    • 引用对象方法
      • 实例化对象 :: 普通方法 ;
      • filter(heros, testLambda::testHero);
    • 引用容器中的对象的方法
      • 特定类 :: 普通方法
      • filter(heros, Hero::matched);
    • 引用构造器
      • 类名称 :: new
      • 接口中的方法返回一个对象:public interface Supplier<T> {T get();}
      • 设计一个方法以这个接口为参数:public static List getList(Supplier<List> s){return s.get();}
      • 调用这个方法,有三种方式
        • 匿名类:Supplier<List> s = new Supplier<List>() {public List get() {return new ArrayList();}}; List list1 = getList(s);
        • Lambda表达式:List list2 = getList(()->new ArrayList());
        • 引用构造器:List list1 = getList(ArrayList::new);
     1 @FunctionalInterface
     2 interface IMessage<P,R>{
     3     public R zhuanhuan(P p);
     4 }
     5 
     6 public class MethodReference_Demo {
     7     public static void main(String[] args) {
     8         IMessage<Integer,String> msg = String::valueOf;
     9         String str = msg.zhuanhuan(1000);
    10         //以上两句等价于
    11         //String str = String.valueOf(1000);
    12         System.out.println(str.replace("0", "9"));
    13     }
    14 }
    View Code

     内建函数式接口

    • 任何语言推出了一项技术之后,都会在语言本身围绕这个技术点进行大量的结构性完善
    • 函数式接口可分为四类,定义函数式接口时,直接使用内置的四种类型即可
    • 功能型接口(Function<T,R>):接收一个参数,返回一个结果
    • 消费型接口(Consumer<T>):负责接收数据,且不返回结果
    • 供给型接口(Supplier<T>):不接受参数,但可返回结果
    • 断言型接口(Predicate<T>):进行判断操作

    聚合操作

    • 快速的数据处理的操作,工作在类集上
    • Lambda表达式、方法引用、四个函数式接口
    • Collection的父接口Iterable接口中定义的方法
      • default void forEach(Consumer<? super T> action):对Iterable的每个元素执行给定的操作
      • Consumer<? super T> action:消费型函数接口,能接收参数,但没有返回值
      • foreach()只能只能实现输出,主要使用Iterator迭代
    • Stream可利用Collection接口提供的方法
      • 并行数据流计算:default Stream<E> parallelStream()
      • 数据流计算:default Stream<E> stream()
      • 性能高:流计算比Iterator迭代的性能快100倍左右
      • 语法简单
    • 聚合操作遍历数据
      • List<Hero> heros = new ArrayList<Hero>();
      • heros.stream().filter(h -> h.hp > 100 && h.damage < 50).forEach(h -> System.out.println(h.name));
    • Stream和管道
      • Stream是一系列元素,管道指聚合操作
    • 管道源
      • List<Hero> heros.stream()
    • 中间操作
      • 每个中间操作返回一个Stream,不会进行真正遍历
      • filter:匹配
      • distinct:去重
      • sorted:排序
      • sorted(Comparator<T>):指定排序
      • limit:取出的最大数据量
      • skip:跳过多少数据量
    • 结束操作
      • 不返回Stream,执行中间操作的行为
      • forEach():遍历每个元素
      • toArray():转换为数组
      • min(Comparator<T>):取最小元素
      • max(Comparator<T>):取最大元素
      • count():总数
      • findFirst():第一个元素

    forEach()

     1 import java.util.ArrayList;
     2 import java.util.List;
     3 
     4 public class Stream_Demo {
     5     public static void main(String[] args) throws Exception{
     6         List<String> all = new ArrayList<String>();
     7         all.add("Hello");
     8         all.add("World");
     9         all.add("Good");
    10         all.forEach(System.out::println);
    11     }
    12 }
    View Code

    判断包含“j”的单词个数

     1 import java.util.ArrayList;
     2 import java.util.Collections;
     3 import java.util.List;
     4 import java.util.stream.Stream;
     5 
     6 public class Stream_Demo {
     7     public static void main(String[] args) throws Exception{
     8         List<String> all = new ArrayList<String>();
     9         Collections.addAll(all,"Java","JavaScript","Ruby","Python");
    10         Stream<String> stream = all.stream();
    11         System.out.println(stream.filter((ele)->ele.toLowerCase().contains("j")).count());
    12     }
    13 }
    View Code

    取出包含“j”的单词

     1 import java.util.ArrayList;
     2 import java.util.Collections;
     3 import java.util.List;
     4 import java.util.stream.Collectors;
     5 import java.util.stream.Stream;
     6 
     7 public class Stream_Demo {
     8     public static void main(String[] args) throws Exception{
     9         List<String> all = new ArrayList<String>();
    10         Collections.addAll(all,"Java","JavaScript","Ruby","Python");
    11         Stream<String> stream = all.stream();
    12         List<String> subList = stream.filter((ele)->ele.toLowerCase().contains("j")).collect(Collectors.toList());
    13         System.out.println(subList);
    14     }
    15 }
    View Code

    取出1个包含“j”的单词,跳过1个元素

     1 import java.util.ArrayList;
     2 import java.util.Collections;
     3 import java.util.List;
     4 import java.util.stream.Collectors;
     5 import java.util.stream.Stream;
     6 
     7 public class Stream_Demo {
     8     public static void main(String[] args) throws Exception{
     9         List<String> all = new ArrayList<String>();
    10         Collections.addAll(all,"Java","JavaScript","Ruby","Python");
    11         Stream<String> stream = all.stream();
    12         List<String> subList = stream.filter((ele)->ele.toLowerCase().contains("j")).skip(1).limit(1).collect(Collectors.toList());
    13         System.out.println(subList);
    14     }
    15 }
    View Code

     

    MapReduce

    • Google提出的分布式数据处理模型
      • Map:对数据进行先期处理,可能需要计算、转型等
      • Reduce:数据的统计计算,针对处理好的数据内容进行统计操作

    数据分析

     1 import java.util.ArrayList;
     2 import java.util.DoubleSummaryStatistics;
     3 import java.util.List;
     4 
     5 class Order{
     6     private String name;
     7     private double price;
     8     private int amount;
     9     public Order(String name, double price, int amount) {
    10         this.name = name;
    11         this.price = price;
    12         this.amount = amount;
    13     }
    14     public String getName() {
    15         return name;
    16     }
    17     public double getPrice() {
    18         return price;
    19     }
    20     public int getAmount() {
    21         return amount;
    22     }    
    23 }
    24 
    25 public class MapReduce_Demo {
    26     public static void main(String[] args) throws Exception{
    27         List<Order> all = new ArrayList<>();
    28         all.add(new Order("PagePig",19.8,200));
    29         all.add(new Order("BigPig",0.8,100));
    30         all.add(new Order("WaWaPig",32000,10));
    31         all.add(new Order("Java",100,200));
    32         DoubleSummaryStatistics statistics = all.stream().filter((ele)->ele.getName().contains("Pig")).mapToDouble((orderObject)->orderObject.getPrice()*orderObject.getAmount()).summaryStatistics();
    33         System.out.println("购买数量 "+statistics.getCount());
    34         System.out.println("总花销 "+statistics.getSum());
    35         System.out.println("最高价格 "+statistics.getMax());
    36         System.out.println("最低价格 "+statistics.getMin());
    37         System.out.println("平均价格 "+statistics.getAverage());
    38     }
    39 }
    View Code
  • 相关阅读:
    linux基本命令
    Linux中常用的50个命令
    Selenium2之XPath定位
    Selenium2浏览器启动及配置
    python学习内容.05
    python学习内容.04
    python学习内容.03
    python学习内容.02
    python学习内容.01
    RESTful
  • 原文地址:https://www.cnblogs.com/cxc1357/p/12454444.html
Copyright © 2020-2023  润新知