美文网首页
JDK1.8-Lambda表达式

JDK1.8-Lambda表达式

作者: 顺利_4364 | 来源:发表于2019-01-15 20:38 被阅读0次

一、Lambda表达式及函数式接口介绍

1. 描述

Lambda表达式是Java8中最重要的新功能之一。使用Lambda表达式可以替代只有一个抽象函数的接口实现, 告别匿名内部类,代码看起来更简洁易懂。Lambda表达式同时还提升了对集合、框架的跌代、遍历、过滤数据的操作。

2. 特点

  • 函数式编程
  • 参数类型自动推断
  • 代码量少,简洁

3. 如何学习

  • 熟悉泛型
  • 多练, 多用Stream API

4. Lambda表达式使用场景

  • 任何有函数式接口的地方
  • 函数式接口: 只有一个抽象方法的接口, 排除 Object中的方法, default, static修饰的方法.

5. 函数式接口定义

  1. 定义只有一个抽象方法的接口
  2. 在接口上加注解@FunctionalInterface

示例

@FunctionalInterface
public interface DemoLambda2 {

    int delete();

    // Object中的方法不包括
    public int hashCode();

    // default修饰的不包括
    default int insert(){
        return 1;
    }
    // static修饰的不包括
    static void update() {}
}

6. JDK1.8中定义的Lambda表达式

  • Supplier<T>: 代表一个输出
@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}
  • Consumer<T>: 代表一个输入
@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);
}
  • BiConsumer<T, U>: 代表2个输入.
@FunctionalInterface
public interface BiConsumer<T, U> {

    /**
     * Performs this operation on the given arguments.
     *
     * @param t the first input argument
     * @param u the second input argument
     */
    void accept(T t, U u);
}
  • Function<T, R>: 代表一个输入, 一个输出(一般输入和输出是不同类型的)
@FunctionalInterface
public interface Function<T, R> {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);
}
  • UnaryOperator<T>: 代表一个输入, 一个输出(输入和输出是相同类型)
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
}
  • BiFunction<T, U, R>: 代表2个输入, 一个输出.(一般输入输出不同)
@FunctionalInterface
public interface BiFunction<T, U, R> {

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    R apply(T t, U u);

  • BinaryOperator: 代表2个输入, 一个输出 (输入和输出是相同类型的)
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
}

二、Lambda表达式详解

1. Lambda表达式

  1. Lambda表达式是对象, 是一个函数式接口的实例.

2. Lambda表达式语法

  • 语法: LambdaParameters -> lambdaBody
    例子
    Runnable r = () -> Systerm.out.print("例子");
  • 自己理解如下:
    函数式接口定义的方法中的参数是LambdaParameters, 加上->, 实现函数式接口的具体内容是lambdaBody.

三、方法的引用(一)

方法的引用: 用来直接访问类或者实例的已经存在的方法或构造方法, 方法引用提供了一种引用而不执行方法的方式, 如果抽象方法的实现恰好可以使用调用另外一个方法来实现, 就有可能使用方法引用.

方法引用分类

类型 语法 对应的lambda表达式
静态方法引用 类名::staticMethod (args)->类名.staticMethod(args)
实例方法引用 inst::instMethod (args)->inst.instMethod(args)
对象方法引用 类名::instMethod (args)->类名.instMethod(args)
构造方法引用 类名::new (args)->new 类名(args)

静态方法引用

定义: 如果函数式接口的实现恰好是通过调用一个静态方法来实现, 那么就可以使用静态方法使用.

实例方法引用

定义: 如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现, 那么就可以使用实例方法引用

语法: inst::instMethod

对象方法引用

定义: 函数是接口中的抽象方法的第一个参数类型刚好是实例的类型, 抽象方法剩余的参数恰好可以当做实例方法的参数. 如果函数式接口的实现能由上面说的实例方法调用来实现的话, 那么就可以使用对象方法引用.

  • 抽象方法的参数类型. 而不是抽象接口.例如:
  • 对象方法引用适用于自定义对象.
   /**
     * 注意不要用函数式接口的泛型参数来对比参数:
     * 比如函数式接口: BiFunction<DemoLamda5, String, String>
     *  要对比它的抽象方法: R apply(T t, U u);
     *  第一个参数T, 要是实例的类型DemoLamda5
     *  第二个参数U, 要是实例方法getA(String b)的参数b类型一致
     *  R是出参, 不是抽象方法的入参.
     */
public class DemoLamda5 {

    public String getA(String b) {
        return b;
    }

    public void test1() {

        BiFunction<DemoLamda5, String, String> biFunction = (a, b) -> new DemoLamda5().getA(b);
        BiFunction<DemoLamda5, String, String> biFunctio2n = DemoLamda5::getA;
    }
}


构造方法引用

定义: 如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现, 那么就可以使用构造方法引用.

  • 注意: 构造方法引用适用于无参的构造方法. 有参也可以使用.
public class DemoLambda6 {

    public void testConst() {
        // 全写
        Supplier<Person> supplier = () -> {
            return new Person();
        };

        // 构造方法引用写法
        Supplier<Person> supplier1 = Person::new;
    }
}

五、Stream API

英文定义: A sequence of elements supporting sequential and parallel aggregate operations
Stream是一组用来处理数组、集合的API

特性

  • 不是数据结构, 没有内部存储
  • 不支持索引访问
  • 延迟计算
  • 支持并行
  • 很容易生成数组或集合(List, Set)
  • 支持过滤, 查找, 转换, 汇总, 聚合等操作.

Stream运行机制

  • Stream分为源source, 中间操作, 终止操作。
  • 流的源可以是一个数组、 一个集合、 一个生成器方法、 一个I/O通道等等.
  • 一个流可以有零个或多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作。
  • Stream只有遇到终止操作,它的源才开始执行遍历操作。

Stream的创建

  1. 通过数组
  2. 通过集合
  3. 通过Stream.generate方法来创建
  4. 通过Stream.iterate方法来创建
  5. 其他API创建.

Stream常用API

中间操作

  • 过滤 filter
  • 去重 distinct
  • 排队 sorted
  • 截取 limit, skip
  • 转换 map/flatmap
  • 其他 peek

终止操作

  • 循环 foreach
  • 计算 min, max, count, average
  • 匹配 anyMatch, allMatch, noneMatch, findFirst, findAny
  • 汇聚 reduce
  • 收集器 toArray, collect

七、 Lambda表达式、方法的引用、Stream API实战

相关文章

  • JDK1.8-Lambda表达式

    一、Lambda表达式及函数式接口介绍 1. 描述 Lambda表达式是Java8中最重要的新功能之一。使用Lam...

  • Twig表达式

    Twig 表达式分为字面表达式、数学表达式、逻辑表达式、比较表达式、包含表达式、测试表达式、字符串插值表达式及其它...

  • php第五天--基本函数

    for变形格式for (表达式1; 表达式2; 表达式3) {循环体} 表达式1;for (; 表达式2; 表达式...

  • Python推导式(列表推导式、元组推导式、字典推导式和集合推导

    列表表达式 元祖表达式 字典表达式 集合表达式

  • 表达式

    原始表达式 最简单的表达式是“原始表达式”。原始表达式是表达式的最小单位,它们不再包含其他表达式。js中原始表达式...

  • 三元运算符

    基本格式 :(关系表达式) ? 表达式1 : 表达式2;执行流程 :关系表达式为 [真] 返回表达式1关系表达式为...

  • for循环

    for(表达式1;表达式2;表达式3){ //循环操作(输出) } 表达式1:循环变量的声明表达式.(a=...

  • daily -- mysql 基础 分支语句( if and

    if函数 语法:IF(表达式1,表达式2,表达式3); 如果表达式1成立(true),返回表达式2的值;如果表达式...

  • 表达式树

    表达式树中缀表达式转换为后缀表达式后缀表达式总结

  • linux 中 if 语句条件的含义

    文件表达式 整数变量表达式 字符串变量表达式 if [ 表达式1 –o 表达式2 ]

网友评论

      本文标题:JDK1.8-Lambda表达式

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