数组引用,是 Lambda 针对数组的一种写法!

Posted xiaoxi1314

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组引用,是 Lambda 针对数组的一种写法!相关的知识,希望对你有一定的参考价值。

 


一、Lambda 表达式

1、什么是 Lambda 表达式?

  Lambda 本质是一个匿名函数,可以理解为一段可以传递的代码,像数据一样传输。
  使用 Lambda 可以简化代码、使代码更紧凑、更灵活。
  使用 Lambda 表达式前提 需要函数式接口支持。
注:
  函数式接口:指的是 接口中只有一个抽象方法的接口。可以使用 @FunctionalInterface 注解去判断、检查是否为函数式接口。

技术图片
技术图片
@FunctionalInterface
public interface Test {
    public void test();

    // public void test2();
}
技术图片
技术图片

技术图片

 

 

 技术图片

 

 

 

2、基础语法:

  JDK 8 引入一个箭头操作符 “->”,或者叫 Lambda 操作符。

技术图片
技术图片
技术图片
【格式:】
    (参数列表) -> {Lambda 体};
注:
    参数列表指的是 方法的参数,即需要在 Lambda 体中执行的变量。
    Lambda 体指的是 方法体,定义了需要执行的功能。

【语法:】
    若出现一个参数的情况,可以将()省略。
    若出现一行代码的情况,可以将{}省略。
    对于多个参数的情况,可以省略参数类型(JVM 类型推断),但()不能省略。
    若{}中只有一行代码,且为return语句,则可省略return 和 {}。
技术图片
技术图片
技术图片

 

3、举例:

  如下例,使用匿名函数 与 Lambda 的比较。
  Lambda 可以省去很多代码,代码结构紧凑、简洁。
  使用 Lambda 与使用 匿名函数类似, Lambda 体中即为 匿名函数重写的方法的方法体,参数列表为 匿名函数重写的方法的参数列表,使用时,直接调用方法名即可。

技术图片
技术图片
技术图片
【举例:】

/**
 * 测试 Lambda 表达式用法
 */
public class TestLambda {
    public static void main(String[] args) {
        String str = "helloworld";
        // 使用 匿名函数 时
        test(str, new TestLambdaFunction() {
            @Override
            public void test(String str) {
                System.out.println(str);
            }
        });

        // 使用 Lambda 表达式,此方法等价于上面匿名函数的写法
        // 只有一个参数,() 可省略,参数类型可省略(JVM自动进行类型推断), Lambda 体只有一行代码,{} 可省略。
        test(str, x -> System.out.println(x));
    }

    public static void test(String str, TestLambdaFunction testLambdaFunction) {
        testLambdaFunction.test(str);
    }
}

@FunctionalInterface
interface TestLambdaFunction {
    void test(String str);
}
技术图片
技术图片
技术图片

技术图片

 

 

 

4、核心函数式接口

  使用 Lambda 表达式前提是为函数式接口,但是 每次都自定义函数式接口,很繁琐、蛋疼,所以 Java 8 内置了函数式接口,使用时套用即可。

技术图片
技术图片
技术图片
【四大核心函数式接口:(其余函数式接口用法类似)】
    Consumer<T>          消费型接口,有参数 T,没有返回值。
        抽象方法: void accept(T t);

    Supplier<T>              供给型接口,没有参数,有返回值 T。
        抽象方法: T get();  

    Function<T, R>         函数型接口,有参数 T,有返回值 R。
        抽象方法:R apply(T var1);
    
    Predicate<T>             断言型接口,有参数 T,返回值为 boolean 型。
        抽象方法: boolean test(T var1);


【举例:】

import java.util.Date;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 测试 Lambda 表达式用法
 */
public class TestLambda {
    public static void main(String[] args) {
        String str = "helloworld";
        // 测试 Consumer<T> 函数式接口,此处定义 Consumer<T> 函数式接口抽象方法的具体实现
        testConsumer(str, x -> System.out.println(x));

        // 测试 Supplier<T> 函数式接口,此处定义 Supplier<T> 函数式接口抽象方法的具体实现
        testSupplier(() -> new Date());
    }

    public static void testConsumer(String str, Consumer<String> consumer) {
        // 此处为 Consumer<T> 函数式接口抽象方法具体调用
        consumer.accept(str);
    }

    public static void testSupplier(Supplier<Date> supplier) {
        // 此处为 Supplier<T> 函数式接口抽象方法具体调用
        System.out.println(supplier.get());
    }
}
技术图片
技术图片
技术图片

技术图片

 

 

 

5、方法引用

  若 Lambda 体中的内容在其他方法中已经实现,可以通过 方法引用 去引用相关代码,从而减少代码的冗余。方法引用可以理解为 Lambda 的另一种表现形式。

技术图片
技术图片
技术图片
【格式:】
    对象名::实例方法名
    类名::静态方法名
    类名::实例方法名   
注:
    方法引用 的方法与函数式接口中的方法 返回值类型 以及 参数类型要一致。
    当 Lambda 参数列表中 第一个参数 是实例方法的调用者,第二个参数是 实例方法的参数时,才可以使用 类::实例方法名。 比如:String::equals.
    
【举例:】

import java.io.PrintStream;
import java.util.function.Consumer;

/**
 * 测试 Lambda 表达式用法
 */
public class TestLambda {
    public static void main(String[] args) {
        Consumer<String> consumer0 = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer0.accept("匿名函数");

        // 一般 Lambda 表达式写法
        Consumer<String> consumer1 = x -> System.out.println(x);
        consumer1.accept("hello");

        PrintStream printStream = System.out;

        Consumer<String> consumer2 = x -> printStream.println(x);
        consumer2.accept("hello wrold");

        // 使用 对象名::实例方法名 去改写 Lambda 表达式,本质与 Lambda 表达式一致
        Consumer<String> consumer3 = printStream::println;
        consumer3.accept("world");
    }
}
技术图片
技术图片
技术图片

技术图片

 

 

 

6、构造器引用

  与方法引用类似,此处是对构造器的引用,是 Lambda 针对构造器的一种写法。

技术图片
技术图片
技术图片
【格式:】
    类名::new
注:
    构造器引用 的参数列表 与 函数式接口中方法的参数列表 要一致。
    即通过方法参数去确认调用哪一个构造方法。

【举例:】

import java.util.function.Function;

/**
 * 测试 Lambda 表达式用法
 */
public class TestLambda {
    public static void main(String[] args) {
        // 普通 Lambda 表达式
        Function<String, String> function = (x) -> new String(x).trim();
        System.out.println(function.apply("       ddd hello "));

        // Lambda 表达式 -- 构造器引用
        Function<String, String> function1 = String::new;
        System.out.println(function1.apply("      hello "));

        // 普通 Lambda 表达式,并创建一个对象实例,等价于 上面的构造器引用
        Function<String, String> function2 = (x) -> new String(x);
        System.out.println(function2.apply("      hello "));
    }
}
技术图片
技术图片
技术图片

技术图片

 

 

 

7、数组引用

  与方法引用类似,此处是对数组引用,是 Lambda 针对数组的一种写法。

技术图片
技术图片
技术图片
【格式:】
    数组类型[]::new

【举例:】

import java.util.function.Function;

/**
 * 测试 Lambda 表达式用法
 */
public class TestLambda {
    public static void main(String[] args) {
        // 一般 Lambda 创建一个数组的写法
        Function<Integer, String[]> function = x -> new String[x];
        System.out.println(function.apply(10).length);

        // 使用数组引用创建一个 数组的写法
        Function<Integer, String[]> function1 = String[]::new;
        System.out.println(function1.apply(20).length);
    }
}
技术图片
技术图片
技术图片

技术图片

 

二、Stream API

1、什么是 Stream API?

  Stream API 是 JDK 8 中处理集合的抽象概念,可以对指定的集合进行复杂的操作,比如查找、过滤、映射数据等。
  简单地理解:Stream API 提供了一种高效且易于使用的处理数据的方式。Stream 就是一个数据通道,一个数据 经过 该通道(一系列流水线操作)后得到一个新的数据。
  Stream 不会存储数据、不会改变源对象(会创建一个新 Stream)、延迟操作。

2、Stream 操作步骤

  Step1:创建流。
  Step2:流水线操作(对流进行操作)。
  Step3:终止流。

以上是关于数组引用,是 Lambda 针对数组的一种写法!的主要内容,如果未能解决你的问题,请参考以下文章

004 方法引用

JavaScript 中的 for 循环---------------引用

使用lambda求数组和

java 基本语法(十七)Lambda 构造器引用与数组引用

ECSHOP的JS文件代入问题

浅谈集合与引用