Java函数式编程

目录

函数式编程基础

函数作为头等对象

纯粹的函数

高阶函数

没有状态

无副作用

函数接口


函数式编程基础

函数式编程包含以下关键概念:

  • 作为第一类对象的功能
  • 纯粹的功能
  • 高阶函数

纯函数式编程也有一套遵循的规则:

  • 没有状态No State
  • 无副作用
  • 不可变的变量
  • 支持递归胜过循环

即使您不是一直遵循所有这些规则,您仍然可以从应用程序中的函数式编程思想中受益。正如您将看到的,函数式编程并不是解决每个问题的正确工具。特别是“没有副作用”的想法使得,例如难以写入数据库(这是副作用)。您需要了解函数式编程擅长解决哪些问题,哪些不是。

函数作为头等对象

这意味着你可以创建一个函数的“实例”,就像函数实例的变量引用一样,就像对String,Map或任何其他对象的引用一样。函数也可以作为参数传递给其他函数。

在Java中,方法不是头等对象。我们得到的最接近的是Java Lambda Expressions。

纯粹的函数

在以下情况下,函数是纯函数:

  • 该函数的执行没有副作用。
  • 函数的返回值仅取决于传递给函数的输入参数。
public class ObjectWithPureFunction{

    public int sum(int a, int b) {
        return a + b;
    }
}

注意sum()函数的返回值如何仅取决于输入参数。另请注意,sum()没有副作用,这意味着它不会修改函数外部的任何状态(变量)。

相反,这是一个非纯函数的例子:

public class ObjectWithNonPureFunction{
    private int value = 0;

    public int add(int nextValue) {
        this.value += nextValue;
        return this.value;
    }
}

注意方法add()如何使用成员变量来计算其返回值,它还修改了值成员变量的状态,因此它有副作用。

高阶函数

如果满足以下条件中的至少一个,则函数是高阶函数:

  • 该函数将一个或多个函数作为参数。
  • 该函数返回另一个函数作为结果。

在Java中,我们可以获得更高阶函数的最接近的函数(方法)是将一个或多个lambda表达式作为参数,并返回另一个lambda表达式。

public class HigherOrderFunctionClass {

    public  IFactory createFactory(IProducer producer, IConfigurator configurator) {
        return () -> {
           T instance = producer.produce();
           configurator.configure(instance);
           return instance;
        }
    }
}

IProducer 和IConfigurator是函数接口,而java lambda表达式可以实现一个函数接口;并且createFactory() 返回了一个函数接口。

public interface IFactory {
   T create();
}
public interface IProducer {
   T produce();
}
public interface IConfigurator {
   void configure(T t);
}

没有状态

“无状态”通常表示该功能外部没有状态。函数可以在内部包含包含临时状态的局部变量,但该函数不能引用该函数所属的类或对象的任何成员变量。一下是无外部状态的实例:

public class Calculator {
    public int sum(int a, int b) {
       return a + b;
    }
}

相反,这是一个使用外部状态的函数示例:

public class Calculator {
    private int initVal = 5;
    public int sum(int a) {
       return initVal + a;
    }
}

无副作用

这意味着,函数不能更改函数外的任何状态。改变了在函数外部的状态被称为副作用。函数外部的状态既指代类中的成员变量,也指成员函数,参数中的成员变量指向函数,或者指向外部系统中的状态,如文件系统或数据库。

不可变的变量

函数式编程范例中的第三条规则是不可变变量。不可变的变量使得更容易避免副作用。

支持递归胜过循环

函数式编程范例中的第四条规则是支持递归而不是循环。递归使用函数调用来实现循环,因此代码变得更加实用。循环的另一种替代方法是Java Streams API。

函数接口

public interface MyInterface {
    public void run();
}

public interface MyInterface2 {
    public void run();

    public default void doIt() {
        System.out.println("doing it");
    }

    public static void doItStatically() {
        System.out.println("doing it statically");
    }
}

函数接口还可以参看 :https://blog.csdn.net/liao_hb/article/details/90081652#Functional%20interfaces

请注明出处。

你可能感兴趣的:(语言基础)