Java8 stream新定义运算

动机

java的Stream在批量处理数据方面很强大。但是在面对类似json等每部分都有不同语义的数据时就力不心了。正因为不像列表或集合,json数据常常每部分有不同语义,所以要交由不同模块来处理。而最常用的map方法。只允许我们嵌入一个映射函数。当然,你可以在map函数里用if else 选择函数,但这就耦合了。(其实用groupingByentrySet().stream()也不错,但是就不能惰性求值了)于是我写了个Function实现类select。根据select注入模块。模块只要做好自己的工作就好了,不用管数据从哪里来,从何而来,什么时候来。
本来想写个定位数据的功能,再把定位的数据交给处理模块,但发现太复杂了,其实只关注当前层和下一层会让方法简单。

select

package cn.lyf.demo;

import java.util.function.*;
import org.springframework.context.*;
import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;

@Component
public class SelectBuilder {
    @Autowired
    ApplicationContext applicationContext;

    public <T, R> Function<T, R> build(Function<? super T, String> dispatcher, Class<R> r) {
        return new Select<>(dispatcher, r)::apply;
    }

    public <T,R> Function<T,?> build(Function<? super T, String> dispatcher) {
        return new Select<>(dispatcher)::apply;
    }

    // 逻辑不等价
    // 用select 列操作
    public class Select<T, R> implements Function<T, R> {

        private Function<T, String> dispatcher;

        @Override
        @SuppressWarnings("unchecked")
        public R apply(T arg0) {
            Function<T, ?> fx = (Function<T, ?>) applicationContext.getBean(dispatcher.apply(arg0));
            return (R) fx.apply(arg0);
        }

        public Select(Function<T, String> dispatcher) {
            this.dispatcher = dispatcher;
        }

        public Select(Function<T, String> dispatcher, Class<R> r) {
            this.dispatcher = dispatcher;
        }

    }
}

另外一个问题就是stream似乎不支持把某个中间数据交给多个函数处理。类似神经网络那样。

在这里插入图片描述
实现类似下图矩阵的效果

( a b c ) × ( f g h ) → ( f ∗ a g ∗ a h ∗ a f ∗ b g ∗ b h ∗ b f ∗ c g ∗ c h ∗ c ) → ( f ∗ a + g ∗ a + h ∗ a f ∗ b + g ∗ b + h ∗ b f ∗ c + g ∗ c + h ∗ c ) \quad \begin{pmatrix} a \\ b \\ c \end{pmatrix} \quad \times \quad \begin{pmatrix} f & g & h \end{pmatrix} \quad \to \quad \begin{pmatrix} f*a & g*a & h*a \\ f*b & g*b & h*b \\ f*c & g*c & h*c \end{pmatrix} \quad \to \quad \begin{pmatrix} f*a + g*a + h*a \\ f*b + g*b + h*b \\ f*c + g*c + h*c \end{pmatrix} \quad abc×(fgh)fafbfcgagbgchahbhcfa+ga+hafb+gb+hbfc+gc+hc
这里和线性代数里的矩阵不一样,我自创的。

这里的*+不是狭义的乘法加法。*可以看作函数调用。+可以看作把结果合并在一起的操作。

为什么最终要把每行加起来呢,其实是我是想为了每次运算不改变数据结构,如果输入是3X1那么输出也是3X1。从逻辑上也讲得通给一个数据获取一个结果。如果你不想把每行数据合在一起就用list::add当作accumulator就行了.

fork

package cn.lyf.demo;

import java.util.*;
import java.util.function.*;
import org.springframework.context.*;
import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;

@Component
public class ForkBuilder {
    @Autowired
    ApplicationContext applicationContext;

    public <T, R> Function<T, R> build(R identity, BinaryOperator<R> accumulator, Supplier<List<String>> getBeans) {
        return new Fork<>(identity, accumulator, getBeans)::apply;
    }

    // 列表里是逻辑等价的
    // 用fork 行操作
    public class Fork<T, R> implements Function<T, R> {
        BinaryOperator<R> accumulator;
        Function<T, R>[] fxs;

        @SuppressWarnings("unchecked")
        public Fork(R identity, BinaryOperator<R> accumulator, Supplier<List<String>> getBeans) {
            this.accumulator = accumulator;
            fxs = getBeans.get().stream().map(s -> applicationContext.getBean(s)).toArray(Function[]::new);
        }

        @Override
        public R apply(T t) {
            List<R> result = new ArrayList<>();
            for (Function<T, R> fx : fxs)
                result.add(fx.apply(t));
            return result.stream().reduce(accumulator).get();
        }

    }

}

二阶操作

初步设想是用fork当行操作,select当列操作,控制每列的fork。这个行列的分类依据是同一行里的各个元素逻辑上是不同维度的(像身高,体重的关系)。同一列逻辑上是同一维度的(像小明的身高和小红身高的关系)。
( a b c d ) × ( f g h w ) → ( f ∗ a + g ∗ a h ∗ b + w ∗ b f ∗ c + g ∗ c h ∗ d + w ∗ d ) \quad \begin{pmatrix} a & b \\ c & d \end{pmatrix} \quad \times \quad \begin{pmatrix} f & g \\ h & w\end{pmatrix} \quad \to \quad \begin{pmatrix} f*a+g*a & h*b+w*b \\f*c+g*c & h*d+w*d \end{pmatrix} \quad (acbd)×(fhgw)(fa+gafc+gchb+wbhd+wd)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值