背景:
看别人的代码加注解,基于jdk 1.8开发各种流式运算和lambda表达式,刚开学习有什么不对请大神赐教
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - -
业务背景:
从一个list集合中求money的平均值
上代码
@Test
public void getLast120dayMeanOrdAmt() {
List<OrderInfoIndex> successTradeList = new ArrayList();
successTradeList.add(new B.OrderInfoIndex(123.0));
successTradeList.add(new B.OrderInfoIndex(124.0));
//最早的实现方式,其实并未实现
Tuple<Integer, Double> result = successTradeList.stream()
.reduce(new Tuple<>(), (o, x) -> new Tuple<>(2, x.getMoney()),
(acc, data) -> new Tuple<>(acc.getV1() + data.getV1(), acc.getV2() + data.getV2()));
Tuple<Integer, Double> result = successTradeList.stream()
.reduce(new Tuple<>(0,0.0), (o, x) -> {
int i = o.getV1() + 1;
double v = o.getV2() + x.getMoney();
System.out.println(i + ":" + v);
return new Tuple<>(i, v);
},
(acc, data) -> new Tuple<>( data.getV1(), data.getV2()));
//最简单的方式
successTradeList.stream().collect(Collectors.averagingDouble(OrderInfoIndex::getMoney));
//使用reduce实现
Tuple<Integer, Double> result = successTradeList.stream()
.reduce(new Tuple<>(0, 0.0), (o, x) -> new Tuple<>(o.getV1() + 1, x.getMoney() + o.getV2()),
(acc, data) -> data);
System.out.println(result.getV2() / result.getV1());
}
class OrderInfoIndex{
Double money;
public OrderInfoIndex(Double money) {
this.money = money;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
}
这个类主要是为了装逼
public class Tuple<V1, V2> {
private V1 v1;
private V2 v2;
public Tuple(V1 v1, V2 v2) {
this.v1 = v1;
this.v2 = v2;
}
public Tuple() {
}
public V1 getV1() {
return v1;
}
public void setV1(V1 v1) {
this.v1 = v1;
}
public V2 getV2() {
return v2;
}
public void setV2(V2 v2) {
this.v2 = v2;
}
}
先上一个简单的demo:
@Test
public void test(){
List list = Arrays.asList(new Integer[]{1, 2, 3});
Optional reduce = list.stream().reduce((x, y) -> x + y);
System.out.println(reduce.get());
Integer reduce1 = list.stream().reduce(1, (x, y) -> x + y);
System.out.println(reduce1);
Optional reduce2 = list.stream().reduce(BinaryOperator.maxBy(Comparator.comparingInt(Integer::intValue)));
System.out.println(reduce2.get());
}
reduce方法有三个override的方法:
Optional reduce(BinaryOperator accumulator);
T reduce(T identity, BinaryOperator accumulator);
< U> reduce(U identity,BiFunction < U, ? super T, U> accumulator,BinaryOperator combiner);
identity - 组合器功能的标识值
返回参数类型
accumulator -一个 associative , non-interfering , stateless功能用于将一个额外的元件到结果
依次递减做处理,逻辑写在里面最终只会返回一个结果,并非集合,第一次的代码错误原因
combiner -一个 associative , non-interfering , stateless功能用于组合两个值,它必须与蓄能器功能兼容
结果
我认为是将第一个方法返回参数变成自定义类型,也有人是解决并发问题,reduce操作是并发进行的 为了避免竞争 每个reduce线程都会有独立的result combiner的作用在于合并每个线程的result得到最终结果
https://www.zhihu.com/question/35451347?q=Stream%20%E7%9A%84%20reduce
BinaryOperator的静态方法有两个 maxBy和minBy