Java之函数编程

前言

        本系列文章为在《告别996,开启Java高效编程之门》学习过程中的学习笔记和课外资料补充,希望可以方便自己和其他需要的同学查阅。

Lambda表达式简介

        ①Java8引入的函数式编程风格;

        ②可以理解为一种匿名函数的代替;

        ③通过行为参数传递代码。

Lambda表达式的形式

        (parameters) -> expression

        (parameters) -> { statement; }

形式一:没有参数

 () -> System.out.println("Hello World!");

形式二:只有一个参数

name -> System.out.println("Hello World from " + name + " !");

形式三:没有参数,逻辑复杂

() -> {

        System.out.println("Hello");

        System.out.println("World!");

    }

形式四:包含两个参数的方法

BinaryOperator<Long> functionAdd = (x,y) -> x + y;

Long result = functionAdd.apply(1L, 2L);

形式五:对参数显式声明

BinaryOperator<Long> functionAdd = (Long x, Long y) -> x + y;

Long result = functionAdd.apply(1L, 2L);

函数式接口

        ①接口中只有一个抽象方法;

        ②Java8的函数式接口注解: @FunctionInterface ;

        ③函数式接口的抽象方法签名:函数描述符。

实战案例:自定义函数式接口

        自定义函数式接口,实现读取本地文件后自定义处理逻辑功能。

        1.定义函数式接口

/**

* 文件处理函数式接口

*/

@FunctionalInterface

public interface FileConsumer {

    /**

     * 函数式接口抽象方法

     * @param fileContent - 文件内容字符串

     */

    void fileHandler(String fileContent);

}

        2.通过url获取本地文件内容,调用函数式接口进行处理

package com.pino.lambda.file;

import java.io.*;


public class FileService {
    /**
     * 通过url获取本地文件内容,调用函数式接口进行处理
     * @param url
     * @param fileConsumer
     * @throws IOException
     */
    public void fileHandle(String url, FileConsumer fileConsumer) throws IOException {
        //创建文件读取流
        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream(url)));
        //定义行变量和内容sb
        String line;
        StringBuilder sb = new StringBuilder();

        //循环读取文件内容
        while ((line = bufferedReader.readLine()) != null) {
            sb.append(line + "\n");
        }

        //调用函数式接口方法,将文件内容传递给lambda表达式,实现业务逻辑
        fileConsumer.fileHandler(sb.toString());

    }

}

        3.测试用例

package com.pino.lambda.file;

import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.*;


public class FileServiceTest {

    @Test
    public void fileHandle() throws IOException {
        FileService fileService = new FileService();
        fileService.fileHandle("E:\\learn\\996\\src\\test\\com\\pino\\lambda\\file\\FileServiceTest.java", fileContent -> {
            System.out.println(fileContent);
        });
    }

}

        4.测试结果

Java之函数编程

常用函数接口及使用

接口

参数

返回类型

描述

Predicate<T>

T

boolean

用于判别一个对象。比如判断一个人是否为男性。

Consumer<T>

T

void

用于接收一个对象进行处理但没有返回,比如接收一个人并打印他的名字。

Function<T, R>

T

R

转换一个对象为另一个不同类型的对象。

Supplier<T>

None

T

提供一个对象。

UnaryOperator<T>

T

T

接收对象并返回同类型的对象。

BinaryOperator<T>

(T, T)

T

接收两个同类型的对象,并返回一个原类型对象。

方法引用

        方法引用是调用特定方法的Lambda表达式的一种快捷写法,可以让你重复使用现有的方法定义,并像Lambda表达式一样传递它们。

        格式如下:

Java之函数编程

Optional.ofNullable(cartSkuList)
                    .map(List::stream)
                    .orElseGet(Stream::empty)
                    .sorted(Comparator.comparing(Sku::getTotalNum))
                    .forEach(resultSkuList::add);

        ①指向静态方法的方法引用:

/**
* (args) -> ClassName.staticMethod(args);
* ClassName::staticMethod
*/
public void test1() {
    Consumer<String> consumer1 = (String number) -> Integer.parseInt(number);

    Consumer<String> consumer2 = Integer::parseInt;
}

        ②指向任意类型实例方法的方法引用:

/**
* (args) -> args.instanceMethod();
* ClassName::instanceMethod
*/
public void test2() {
    Consumer<String> consumer1 = (String str) -> str.length();

    Consumer<String> consumer2 = String::length;
}

        ③指向现有对象的实例方法的方法引用:

/**
* (args) -> object.instanceMethod(args);
* object::instanceMethod
*/
public void test3() {
    StringBuilder sb = new StringBuilder();

    Consumer<String> consumer1 = (String str) -> sb.append(str);

    Consumer<String> consumer2 = sb::append;
}

 参考链接:https://blog.csdn.net/icarusliu/article/details/79495534

上一篇:这一次带你搞懂SpringBoot核心原理,一文轻松搞定


下一篇:华为AGC提包检测报告:检测异常