淅奇妈的笔记干货来啦~
一、环境配置支撑:java 11 JDK,Lambok插件,以IDEA为例,确保Annotation Processors中Enable annotaion processing勾选,Lambok plugin中各项勾选。
二、概念及特点:
概念:函数编程强调结果而不是执行过程,利用若干简单的执行单元使得计算结果不断逐层运算。每一次计算都使用上一次计算的结果,函数使用可以更简单处理和更专注于代码逻辑。
特点:a)使用函数不会改变入参函数值; b)函数参数可以多个,返回值也可以是一个函数;
例子1:
.skip(1)跳过一个元素,.peek打印出每个元素,.collection最后收集成一个新的集合。
orderList.stream()
.skip(1)
.peek(name->log.debug("order:{}",order.getOrderId()))
.collection(Collectors.toList());
例子2:
取除了玩具类的,价格前三的订单编码,并输出:
.filter过滤玩具类,.sorted价格倒序,.limit(3)限制前三,.map(Order::getOderId)取订单编码,.distinct去重,.forEach循环遍历打印输出
order->{...}是Lamda表达式的写法,->左边是参数列表,右边是函数体
Order::getOderId方法引用,class::method
orderList stream()
.filter(order->{"玩具".equals(b.getOrderTypeName)})
.sorted((order1,order2)->order2.getPrice().compareTo(order1.getPrice()))
.limit(3)
.map(Order::getOderId)
.distinct()
.forEach(System.out::println);
三、语法:
Lamda表达式,方法引用 class::method:
1、静态方法引用
//调用订单类B中的静态查询方法,Combine中会对数据进行去重 //Combine combine = (a,b)->OrderB.findOrder(a,b); Combine combine = (a,b)->OrderB::findOrder;
2、参数方法引用
//BinFuntion是一个函数式接口,支持输入两个参数,返回一个参数 //BiFunctionparam = (a,b)->a.indexOf(b); BiFunction param = String::indexOf;
3、实例方法引用
Order order = Order.builder().orderTypeName("玩具").build();
//Supplier supplier = ()->order.getOrderTypeName();
Supplier supplier = order::getOrderTypeName;
4、构造器引用
//Suppliersupplier = ()->new Order(); Supplier supplier = Order::new;
四、函数式接口
有且仅有一个为实现的非静态方法的接口叫做“函数式接口”。以下是jdk提供的一些接口
Function函数,Function<入参类型,出参类型>
//Function表示一个函数,Function<入参类型,出参类型> Functionnum = (value)->value + 3 //此步还没有真正修改值 Long resultNum = num.apply((long)8);//真正赋值
Predicate函数,只取一个值作为参数,并返回true或false
Predicate
UnaryOperator函数,入参和出参类型相同
UnaryOperatorunaryOperator = (order)=>{ order.setName("玩具"); return order; }
BinaryOperator函数,两个入参返回一个值得操作
BinaryOperatornum = (a,b)->a+b;
Supplier函数,提供商、提供值
Suppliersupplier = ()=>(int)(Math.random()*1000D);
Consumer函数,一个入参但不返回任何值
Consumerconsumer = (value)->log.debug("{}",value);
注:函数之间可以组合,例如and/or/compose/andthen等
Functiona = (value)->value*value; Function b = (value)->2*value; //组合执行,先执行b,再执行a Function aAndB = a.compose(b)
五、流创建
第一种方式:Arrays.stream
//创建流,arrayList数组转换成流
Array.stream(arrayList)
.peek(order=>log.debug("order:{}",order))//打印
.collect(Collectors.toList())//重新装入新集合
//比较两组集合的长度
assertEquals(arrayList.size(),newList.size());
第二种方式:Collection.stream
//创建流
val list = orderList.stream()
.speek(order->log.debug("order:{}",order))
.collect(Collectors.toList());
第三种方式:Stream.of
//括号中可以任意数组下标的元素组成集合,也可以直接给整个数组集合或者重新实例一个新的
val list = Stream.of(arrayList[0],arrayList[1],arrayList[3])
.speek(order->log.dubug("order:{}",order))
.collect(Collectors.List());
第四种方式:Stream.iterate【迭代器】
val list = Stream.iterate(0,n->n+1)
.limit(10)
.speek(order->log.dubug("order:{}",order))
.collect(Collectors.toList());
第五种方式:Stream.generate【可以理解成工厂方法】,以随机数为例
val list = Stream.generate{()->Math.random()}
.limit(10)
.speek(order->log.debug("order:{}",order))
.collect(Collectors.toList());
第六种方式:IntStream【整型流】
val list = IntStream(0,5)//(0,5)左闭右开,左边包含右边不包含
.boxed()//boxed转换成对象,Stream
.peek(i->log.debug("num:{}",i))
.collect(Collectors.toList());
第七中方式:Stream.builder()
Stream.Buildersb = Stream.builder(); val list = sb.add(arrayOfOrders[0]) .add(arrayOfOrders[1]) .add(arrayOfOrders[2]) .build() .skip(1)//第1个元素不要 .peek(order->log.debug("order:{}",order.getOrderId)) .collect(Collectors.toList());
六、常用基本操作符
1、中间操作符:filter,map【可多个使用,做值的变换】,peek,findAny【返回任意一个】,findFirst
2、终端操作符:forEach,anyMatch【任何匹配】,noneMatch【任何不匹配】,count,min,max
例:findFirst
//查玩具订单中价格最高的一个 val first:Optional= orderList.stream() .filter(order->order.getOrderName().equals("玩具")) .sorted((order1,order2)->order2.getPrice().comparaTo(order1.getPrice())) .findFirst() asserTrue(first.ispresent());//.ispresent()判断是否有值
例:forEach
aList.stream().forEach(order->order.setOrderState("1"));
例:anyMatch
//查找编码满足10023开头的订单
//val existed:Object = orderList.stream()
// .filter(order->order.getOrderId().startsWith("10023")).count()>0
predicate orderAnyMaths = order->order.getOrderId().startsWith("10023");
val existed:Object = orderList.stream()
.anyMath(orderAnyMaths);
例:max
OptionalpriceMax = orderList.stream() .max(Comparator.comparing(Order::getPrice())); assertTrue(priceMax.ispersent());



