前言
本系列文章为在《告别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.测试结果
常用函数接口及使用
接口 |
参数 |
返回类型 |
描述 |
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表达式一样传递它们。
格式如下:
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