如何理解函数式编程的思想

2020-11-04  本文已影响0人  这个世界是虚拟的

说在前面

如果要理解函数式编程, 可能首先要理解什么是函数, 函数在数学上的定义是两组飞空集合的映射, 写法上我们常见 f(x), 这里的 f 就是 function的意思, x就是函数的参数. 举个栗子, f(x) = 2x, 那这个函数的映射就代表了一组 x2乘以x 的映射, 具体点就是, 1对应2, 2对应4, 1.5对应3.

编程中的函数

上面的定义一般大家只要能记起来自己高中学的东西, 就很容易理解, 同时, 应该也能记起来一些常见的函数, 例如, 三角函数等, 同样也有很多复杂的函数分类, 再到大学, 我们学过很多其他复杂的函数, 比如一些变换, 傅里叶变换, 正交变换等等. 等等!!! 我到底想说什么, 其实我想说的是, 复杂的函数, 我们在使用时不会过分关心它是如何实现的(考研的话你还是关心一下).

此时, 我们站在的是函数使用者的角度看问题. 那么, 如果你是函数使用者, 你其实不关心函数的实现, 而只关心这个函数的作用, 比如你要求10的平方, 那你只需要在计算器上按 "x^2".

编程中的函数

那么, 理解了上面的一堆我的瞎BB, 那么接下来我们看看真正编程中, 作为使用者的角度, 如何看待函数. 比如, 给定一个java8 默认函数有很多, 比如

    @Test
    void testFilter() {
        IntStream.rangeClosed(1, 10)
                .filter(x -> x % 2 == 0)
                .forEach(System.out::println);
    }

这是一个简单的打印 1到10 的偶数的方法, 如何从函数的思想理解这个过程? 我们拆解一下这个函数:

    private List<Integer> createArray(){
        List<Integer> list = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }
        return list;
    }

那么现在, 这一步并不是没有实现, 而是被java8实现过了, 你作为使用者的角度, 只需要调用 rangeClosed(1, 10), 和你按计算器没本质的区别.

   private List<Integer> dofilter(@NotNull List<Integer> source) {
        for (Iterator<Integer> iterator = source.iterator(); iterator.hasNext(); ) {
            int x = iterator.next();
            if (x % 2 != 0) {
                iterator.remove();
            }
        }
        return source;
    }

此时,我们只需要给出 x % 2 != 0, 看到这估计聪明的你应该明白为啥单个方法的接口叫函数式接口了,因为这里的比如filter函数, 那它就是一个参数为判断条件IntPredicate的函数, 如果不明白就自己点进源代码看一下

      PrimitiveIterator.OfInt iterator = IntStream.rangeClosed(1, 10).iterator();
        
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

这个例子, 很明显, IntStream.rangeClosed(1, 10) 已经可以拿来继续操作, 但由于开发人员,,不熟悉函数编程, 那么就会导致, 一半寻求使用函数, 一半使用传统编程方式.

对比

传统编程方式, 我们习惯了,写一个函数,然后定义参数,定义返回值,再给定一个实现. 但是函数式编程, 我们往往只需要给定一个实现就可以了, 上面的例子, 过滤时, 你只要给条件即可.

上一篇 下一篇

猜你喜欢

热点阅读