Java Stream/Lambda 表达式
Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
lambda表达式的语法
常规(多参.多语句数)表示语法
(parameters)->{statments}
单参数也可以写为 param->{statments}
单语句也可以写为param->statment
方法引用写法Class or instance :: method
Stream
Stream是对Collection对象功能的增强,对collection类提供了各种非常便利,高效的聚合操作,或者大批量的数据操作.
一般在编写过程中将Lambda与Stream结合起来使用,极大的提高编程效率和程序可读性.但是容易被测试人员揍
关键字:
- filter(过滤器) : 是一个中间操作,接受一个predicate接口类型的变量,并将所有流对象中的元素进行过滤。filter(s -> s.getState()==State.pay)
- map : 是一个对于流对象的中间操作,通过给定的方法,它能够把流对象中的每一个元素对应到另外一个对象上。map(s -> s.getPlanNo()) / map(s -> Plan::planNo) / 价格变成 10倍 map(s -> s.getPrice().multiply(BigDecimal.valueOf(10)))
- reduce:把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),返回单个的结果值,并且reduce操作每处理一个元素总是创建一个新值
例如以下代码:
BigDecimal total = stream().reduce(BigDecimal.zero, (a,b) -> a.add(b));
BigDecimal total = stream().reduce(BigDecimal.ZERO, BigDecimal::add);
- limit : 返回 Stream 的前面 n 个元素
- skip 则是扔掉前 n 个元素
- sorted: 一个中间操作,能够返回一个排过序的流对象的视图。流对象中的元素会默认按照自然顺序进行排序,除非你自己指定一个Comparator接口来改变排序规则
- collect: 修改现存的值,Collectors 类的主要作用就是辅助进行各类有用的 reduction 操作
- groupingBy 按规则分组:stream().collect(Collectors.groupingBy(p->p.getState()))
partitioningBy 是一种特殊的 groupingBy,它依照条件测试的是否两种结果来构造返回的数据结构,get(true) 和 get(false) 能即为全部的元素对象。
示例代码:
public class Plan {
private int id;
private String planNo;
private BigDecimal price;
private long total;
private State state;
private Calendar createTime;
public static List initList(){
List<Plan> ret = new ArrayList<>();
///...省略部分添加元素的代码
return ret;
}
public static void main(String[] args){
List<Plan> planList =initList();
//1.把方案编号planNo转换大写,返回列表
List<String> list1 = planList.stream().map(p->p.planNo.toUpperCase()).collect(Collectors.toList());
//2.价格由高到低排序
List<Plan> list2 = planList.stream().sorted((a,b)->b.price.compareTo(a.price)).collect(Collectors.toList());
//3.状态为支付的价格由高到低的排序
List<Plan> list3 = planList.stream().filter(p->p.state.equals(State.pay)).sorted((a,b)->b.price.compareTo(a.price)).collect(Collectors.toList());
//4.求最高价/最低价/总价, total数量平均,总和 ///
BigDecimal max = planList.stream().max((a,b)->b.price.compareTo(a.price)).get().price;
BigDecimal min = planList.stream().min((a,b)->a.price.compareTo(b.price)).get().price;
BigDecimal total = planList.stream().map(p->p.price).reduce(BigDecimal.ZERO,(a,b)->a.add(b));
//5.总共有多少种状态值
long count = planList.stream().map(p->p.state).distinct().count();
long count2 = planList.stream().map(p->p.state).collect(Collectors.toList()).size();
//6.方案编号中包含某些字符
List<Plan> list4 = planList.stream().filter(p->p.planNo.contains("gt")).collect(Collectors.toList());
//7.价格前三的方案
List<Plan> list5 = planList.stream().sorted((a,b)->b.price.compareTo(a.price)).limit(3).collect(Collectors.toList());
//8.按方案状态分组列表
Map<State,List<Plan>> map = planList.stream().collect(Collectors.groupingBy(p->p.state));
//9.方案分成是否支付两种,查询列表
Map<Boolean,List<Plan>> map1 = planList.stream().collect(Collectors.partitioningBy(s->s.state==State.noPay));
//10.转换成Map结构 《方案,价格》
Map<String, BigDecimal> map4 = planList.stream().collect(Collectors.toMap(p->p.planNo, Plan::getPrice));
//11.转换数据结构,List转成数组
Plan[] plans = planList.stream().toArray(Plan[]::new);
//12.按状态算数量的总和、平均数
//平均
Map<State,Double> map2 = planList.stream().collect(Collectors.groupingBy(Plan::getState,Collectors.averagingLong(Plan::getTotal)))
//求和
Map<State,Long> map3 = planList.stream().collect(Collectors.groupingBy(Plan::getState,Collectors.summingLong(Plan::getTotal)));
}
}
enum State{
noPay,
pay,
settle;
}
这个示例代码是在https://www.cnblogs.com/song27/p/7697713.html里面的示例代码,手敲一遍会加深对stream和lambda表达式的理解.