• Lambda、stream


    Lambda 

    1.Lambda表达式概念

    Lambda表达式是一个匿名函数,可理解为是一段可以传递的代码(即将函数像数据一样传递)。

    Lambda表达式需要函数式接口(即只有一个抽象方法的接口)的支持。

    Lambda操作符:->,该箭头一样的操作符将Lambda表达式拆分成两侧,

                              其中左侧写Lambda表达式的参数列表(接口中抽象方法的参数);右侧写Lambda表达式所需执行的功能(抽象方法的实现),即Lambda体。

    2.Lambda表达式的基本语法

    语法:

    (parameters) -> expression

    (parameters) ->{ statements; }

    3.基础写法

    我们先看几个简单的Lambda表达式的例子:

    // 1. 不需要参数,返回值为 5 

         () -> 5

    // 2. 接收一个参数(数字类型),返回其2倍的值 

          x -> 2 * x

    // 3. 接受2个参数(数字),并返回他们的差值 

          (x, y) ->x –y

    // 4. 接收2个Integer型整数,返回他们的和 

          (Integer x, Integer y) ->x + y

    // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) 

            (String s) ->System.out.print(s)

    通过上述几个简单例子我们总结一下Lambda表达式的基本写法:

    1).左侧类型可以不写;

    2).左侧只有一个参数时小括号也可省略;

    3)右侧只有一条语句时,大括号和return都可省略;

    4)右侧有多条语句,必须要有大括号。

    4.Lambda表达式用在for循环中

    String[] names={"Mike","Mary","Eric","Lucy","Rose"};

    List<String> students=Arrays.asList(names);

    // 以前的循环方式 

    for (String student: students) { 

      System.out.print(student+ "; "); 

       

    //方式一: 使用 lambda 表达式以及函数操作

    students.forEach((student) -> System.out.print(student+ "; ")); 

        

    //方式二:使用双冒号操作符(Lambda表达式方法引用的第一种语法格式,下面会讲  )

    students.forEach(System.out::println);

    5.Lambda表达式的方法引用(双冒号操作符)

    Lambda体中的内容已有方法实现,此时可以使用方法引用,有三种语法格式:

    1)对象::实例方法名

    例:Consumer<String> con=(x)->System.out.println(x);可以写为:

    Consumer<String> con=System.out::println;//System.out即PrintWriter对象

    2)类::静态方法名

    例:Comparator<Integer> com=(x,y)->Integer.compare(x,y);可以写为:

    Comparator<Integer> com=Integer::compare;

    3)类::实例方法名

    例:BiPredicate<String,String> bp=(x,y)->x.equals(y);

    BiPredicate<String,String> bp=String::equals;

    注意:只有当Lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用第3)种语法格式类::实例方法名。如上述例子中第一个参数x是实例方法x.equals(y)的调用者,第二个参数y是方法的参数。

    数据流Stream

    1.流的获取

    1)通过集合Collection获取

    List<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5));

    Stream<Integer> stream = list.stream();

    2)通过数组获取

    String[] array = {"are","you","ok"};

    Stream<String> stream = Array.stream(array);

    //对于基本类型数组的处理

    int[] array = {1,2,3,4,5};

    //此时Arrays.stream(array)获取的是一个IntStream对象

    Stream<Integer> stream = Arrays.stream(array).boxed();    

    3)通过值获取(此方式存在缺陷)

    Stream<String> stream = Stream.of("are","you","ok");

    2.筛选filter

    filter函数接收一个Lambda表达式作为参数,该表达式返回boolean,在执行过程中,流将元素逐一输送给filter,并筛选出执行结果为true的元素;

    //筛选出列表中的非空项

    List<String> list = Arrays.asList("are","you","","ok");

    List<String> filted = list.stream()

                        .filter(x-> !x.empty())

                        .collect(Collectors.toList());

    3.去重、截取、跳过

    去重distinct:

    List<String> list = Arrays.asList("are","you","you","ok");

    List<String> distincted = list.stream()

                            .distinct()

                            .collect(Collectors.toList());

    截取流的前n个元素: .limit(3)

    跳过流的前n个元素: .skip(2)

    4.映射 map

    对流中的每个元素执行一个函数,使得元素转换成另一种类型输出。流会将每一个元素输送给map函数,并执行map中的Lambda表达式,最后将执行结果存入一个新的流中。 

    如:将 list 中每一个 Integer类型元素自增后转化为 String类型

    List<Integer> list = Arrays.asList(1,2,3,4,5);

    List<String> result = list.stream()

                        .map(x->String.valueOf(++x))

                        .collect(Collectors.toList());

    5.合并多个流 flatMap

    List<String> list1 = .....

    List<String> list2 = ...

    List<List<String>> list = Arrays.asList(list1,list2);

    //将list中的list1,list2合并为一个List<String>

    List<String> listsum = list.stream()

                              .flatMap(List::stream)

                              .collect(Collectors.toList());

    以下一个实际的应用例子:列出 list 中各不相同的单词

    List<String> list = new ArrayList<String>();

    list.add("I am a boy");

    list.add("I love the girl");

    list.add("But the girl loves another girl");

    list.stream().map(line->line.split(" "))    //将每一个项分词,并映射为数组

    //将每一个分项数组组合并到主流中,形成一个包含所有分项数组的总数组流

                .flatMap(Arrays::stream)      

                .distinct();                   //去重

                .forEach(System.out::println);   //打印

    6.匹配元素

    1) 是否匹配任一元素:anyMatch

    2) 是否匹配所有元素:allMatch

    3) 是否未匹配所有元素:noneMatch

    7.获取元素

    1) 获取任一元素 :findAny

    2) 获取第一个元素:findFirst

    Optional 对象介绍

    Optional是Java8新加入的一个容器,这个容器只存1个或0个元素,它用于防止出现NullpointException,它提供如下方法:

    • isPresent()  判断容器中是否有值。
    • ifPresent(Consume lambda)  容器若不为空则执行括号中的Lambda表达式。
    • T get()  获取容器中的元素,若容器为空则抛出NoSuchElement异常。
    • T orElse(T other)  获取容器中的元素,若容器为空则返回括号中的默认值。

    8.遍历流 forEach

    forEach方法遍历流中每个元素,参数为一个Lambda表达式,用于对每一个遍历的元素执行的操作;

    //输出10个随机数

    Random random = new Random();

    random.ints().limit(10).forEach(System.out::println);

  • 相关阅读:
    Python字符串的切片
    Python字符串的劈分
    Python函数的参数
    接口幂等性
    Kafka 中的设计思想
    Stream特性
    API接口的安全设计验证:ticket,签名,时间戳
    linux命令
    Java注解和反射
    su 和 sudo
  • 原文地址:https://www.cnblogs.com/HarderYao/p/9896852.html
Copyright © 2020-2023  润新知