我正在参与掘金创作者训练营第5期,点击了解活动详情
简介
面向对象其实是对数据的抽象
函数式编程则是对行为的抽象
核心思想:
使用不可变值和函数,函数对一个值进行处理,映射成另一个值
分类
函数式编程最理想的方式:
形成一个惰性求值的链,最后用一个及早求值的操作返回想要的结果。
类似建造者模式,先是使用一系列操作设置属性和配置,最后调用build方法,创建对象。
惰性求值方法
list.stream.filter(s -> s.equals("string"));
复制代码
就是描述的所需的数据,但是并没有产生结果。
及早求值方法
List<String> newList = list.stream.filter(s -> s.equals("string")).collect(Collectors.toList());
复制代码
最终产生了新的值,并且终止操作
Stream
顺序流
list.stream()
复制代码
并行流
list.stream().parallel()
或
list.parallelStream()
复制代码
并行流的底层就是利用ForkJoinPool进行任务拆分交给不同的线程去执行最后在合并。也就是分治合并
常用函数方法
Filter
过滤函数中符合条件的数据
Map+Reduce
List<Integer> costBeforeTax = Arrays.asList(1, 2, 3);
double bill = costBeforeTax.stream()
.map((cost) -> cost + 12*cost)
.reduce((sum, cost) -> sum + cost).get();
复制代码
map将集合元素装换
reduce将集合数据合并成一个数据
Collectors
- Collectors.joining(", ")
- Collectors.toList()
- Collectors.toSet() ,生成set集合
- Collectors.toMap(MemberModel::getUid, Function.identity())
- Collectors.toMap(ImageModel::getAid, o -> IMAGE_ADDRESS_PREFIX + o.getUrl())
FlatMap
List<Integer> result= Stream.of(Arrays.asList(1,3),Arrays.asList(5,6))
.flatMap(a->a.stream()).collect(Collectors.toList());
复制代码
将多个stream连接成一个stream,flatMap操作的时候其实是先每个元素处理并返回一个新的Stream,然后将多个Stream展开合并为了一个完整的新的Stream
Distinct
去重
count
int countOfAdult=persons.stream()
.filter(p -> p.getAge() > 18)
.map(person -> new Adult(person))
.count();
复制代码
计总数
Match
anyMatch
集合中有一个符合条件就会返回true
allMatch
集合中所有元素都符合条件才会返回true
noneMatch
集合所有元素都不符合条件才会返回true;如果匹配一个元素或者多个元素都会返回false
min、max
使用方式一致,如下
Person a = lists.stream().max(Comparator.comparing(t -> t.getId())).get();
Person a = lists.stream().min(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if (o1.getId() > o2.getId()) return -1;
if (o1.getId() < o2.getId()) return 1;
return 0;
}
}).get();
复制代码
summaryStatistics
统计数组的个数、最小值、最大值、总和以及平均值
List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest prime number in List : " + stats.getMax());
System.out.println("Lowest prime number in List : " + stats.getMin());
System.out.println("Sum of all prime numbers : " + stats.getSum());
System.out.println("Average of all prime numbers : " + stats.getAverage());
复制代码
四大函数接口
消费性接口
Consumer< T> void accept(T t)有参数,无返回值的抽象方法;
复制代码
供给性接口
Supplier < T> T get() 无参有返回值的抽象方法;
复制代码
断定性接口
Predicate<T> boolean test(T t):有参,但是返回值类型是固定的boolean
复制代码
函数性接口
Function<T,R> R apply(T t)有参有返回值的抽象方法;
复制代码
注解 @FunctionInterface
符合哪些条件才能被这个注解修饰
- 首先得是一个接口
- 接口中只能有一个抽象方法,默认方法不算
自定义函数接口
@FunctionalInterface
interface MyFunction<T,R>{
R become(T t);
default void study(){
System.out.println("努力学习!");
}
}
复制代码
四大函数接口编码+自定义函数接口编码
/**
* @author mumuwen
* @className FunctionStudy
* @description: 四大函数式接口,自定义函数式接口
* @date 2022/5/8 16:44
**/
public class FunctionStudy {
private static Map<String,String> myLovePeopleMap = new HashMap<>();
static {
myLovePeopleMap.put("汪","girlfriend");
myLovePeopleMap.put("刘","dad");
myLovePeopleMap.put("张","mom");
}
public static void main(String[] args) {
String name = "刘";
Function<String,Object> function = nm -> new People(myLovePeopleMap.get(nm));
System.out.println(name + function.apply(name));
// 自定义函数式接口
MyFunction<String,Object> myFunction = nm -> nm + "变成了" + new People(myLovePeopleMap.get(nm));
name = "汪";
myFunction.study();
System.out.println(myFunction.become(name));
// 断定性接口
Predicate<String> predicate = nm -> myLovePeopleMap.get(nm) != null;
name = "张";
System.out.println(name + "是我爱的人吗? 请回答:" + predicate.test(name));
// 消费函数
Consumer<String> consumer = food -> System.out.println(food + "被吃掉了");
consumer.accept("汉堡");
// 生产函数
Supplier<People> supplier = () -> {
String relationship = "girlfriend";
return new People(relationship);
};
System.out.println("获得了一个" + supplier.get());
}
}
/**
* 自定义函数式接口
* @param <T> 参数
* @param <R> 返回值
*/
@FunctionalInterface
interface MyFunction<T,R>{
R become(T t);
default void study(){
System.out.println("努力学习!");
}
}
class People{
private String relationship;
public People(String relationship) {
this.relationship = relationship;
}
@Override
public String toString() {
return "我的" + relationship;
}
}
复制代码