函数式编程:Lambda表达式+Stream流式调用+Chain链式调用+Java8函数式接口
Lambda表达式
(parameters) -> expression
或
(parameters) -> { statements; }
parameters:这是Lambda表达式的参数列表。类型可以从上下文推断出来,所以通常可以省略。
->:这是Lambda操作符,它分隔了参数列表和Lambda体。
expression 或 { statements; }:这是Lambda体,可以是一个表达式(返回该表达式的值)或是一个语句块(包含多条语句)。
Stream流式调用
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class FunctionalProgrammingExample {
public static void main(String[] args) {
// 创建一个整数列表
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 使用Stream API和Lambda表达式来过滤偶数并计算它们的平方和
int sumOfSquaresOfEvens = numbers.stream()
.filter(n -> n % 2 == 0) // 过滤偶数
.map(n -> n * n) // 计算平方
.mapToInt(Integer::intValue) // 转换为int流以便求和
.sum(); // 计算总和
// 输出结果
System.out.println("Sum of squares of even numbers: " + sumOfSquaresOfEvens);
// 使用Function接口和链式调用来转换列表中的每个元素
List<String> strings = numbers.stream()
.map(String::valueOf) // 将每个整数转换为字符串
.collect(Collectors.toList()); // 收集到新的列表中
// 输出结果
System.out.println("List of string representations: " + strings);
// 使用Consumer接口来处理列表中的每个元素
numbers.forEach(n -> System.out.print(n + " ")); // 打印每个元素
System.out.println(); // 换行
// 使用Supplier接口来生成一个值
Supplier<Integer> randomNumberGenerator = () -> (int) (Math.random() * 100);
int randomNumber = randomNumberGenerator.get(); // 获取随机生成的整数
// 输出结果
System.out.println("Random number: " + randomNumber);
}
}
Chain链式调用
函数式接口:
-
Runnable:无参数、无返回值
-
Function:接受一个参数,并且有返回值
-
Consumer:接受一个参数,没有返回值
-
BiConsumer:接受两个参数,没有返回值
-
Supplier:没有参数,有返回值
案例
package com.bilibili.juc.cf;
import lombok.*;
import lombok.experimental.Accessors;
import java.awt.print.Book;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*
* 案例说明:电商比价需求,模拟如下情况:
*
* 1需求:
* 1.1 同一款产品,同时搜索出同款产品在各大电商平台的售价;
* 1.2 同一款产品,同时搜索出本产品在同一个电商平台下,各个入驻卖家售价是多少
*
* 2输出:出来结果希望是同款产品的在不同地方的价格清单列表,返回一个List<String>
* 《mysql》 in jd price is 88.05
* 《mysql》 in dangdang price is 86.11
* 《mysql》 in taobao price is 90.43
*
* 3 技术要求
* 3.1 函数式编程
* 3.2 链式编程
* 3.3 Stream流式计算
*/
public class CompletableFutureMallDemo
{
static List<NetMall> list = Arrays.asList(
new NetMall("jd"),
new NetMall("dangdang"),
new NetMall("taobao"),
new NetMall("pdd"),
new NetMall("tmall")
);
/**
* step by step 一家家搜查
* List<NetMall> ----->map------> List<String>
* @param list
* @param productName
* @return
*/
public static List<String> getPrice(List<NetMall> list,String productName)
{
//《mysql》 in taobao price is 90.43
return list
.stream()
.map(netMall ->
String.format(productName + " in %s price is %.2f",
netMall.getNetMallName(),
netMall.calcPrice(productName)))
.collect(Collectors.toList());
}
/**
* List<NetMall> ----->List<CompletableFuture<String>>------> List<String>
* @param list
* @param productName
* @return
*/
public static List<String> getPriceByCompletableFuture(List<NetMall> list,String productName)
{
return list.stream()
.map(
netMall ->
CompletableFuture.supplyAsync(() -> String.format(productName + " in %s price is %.2f",
netMall.getNetMallName(),
netMall.calcPrice(productName)))
)
.collect(
Collectors.toList()
)
.stream()
.map(
s -> s.join()
)
.collect(
Collectors.toList()
);
}
public static void main(String[] args)
{
long startTime = System.currentTimeMillis();
List<String> list1 = getPrice(list, "mysql");
for (String element : list1) {
System.out.println(element);
}
long endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒");
System.out.println("--------------------");
long startTime2 = System.currentTimeMillis();
List<String> list2 = getPriceByCompletableFuture(list, "mysql");
for (String element : list2) {
System.out.println(element);
}
long endTime2 = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime2 - startTime2) +" 毫秒");
}
}
class NetMall
{
@Getter
private String netMallName;
public NetMall(String netMallName)
{
this.netMallName = netMallName;
}
public double calcPrice(String productName)
{
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
}
}