Java8中使用函数式接口进行函数式编程示例 - Vinesh


函数式接口Functional interfaces 为lambda表达式和方法引用提供目标类型。每个函数接口仅包含一个抽象方法,称为函数接口的函数方法, lambda表达式的参数和返回类型将与该方法匹配或适配。java.util.function包含多个函数式接口,例如谓词Predicate,消费者Consumer,供应商Supplier,函数Function,Bi-Function等,可用于实现函数式编程。
 
谓词Predicate
谓词是一个返回布尔值的单参数函数。谓词具有一个test()方法,该方法接受一个参数并返回一个布尔值。例如:

Predicate<Person> personPredicate = 
                  person -> Gender.FEMALE.equals(person.gender);
people.stream().filter(personPredicate)
                .forEach(System.out::println);

filter方法接受谓词来筛选数据,并返回满足谓词一个新的流。
 
函数Function
函数更像是一个泛型函数,它接受一个参数并产生结果。例如,它接受类型T的参数并产生类型R的结果。
public class App {
    public static void main(String[] args) {
        System.out.println(incrementBy1.apply(8));
    }
    
    //Function Interface
    static Function<Integer, Integer> incrementBy1 = num -> num+1;
}

这里的Function接口接受一个整数参数,并返回一个Integer类型的结果。它递增传入的参数整数并返回递增的值作为结果。因此,如果运行此应用程序,则控制台中的结果为9。
我们可以结合使用多个函数以获得所需的输出,让我们看看如何实现这一目标。
public class App {
    public static void main(String[] args) {
        System.out.println(incrementBy1.andThen(multiplyBy10).apply(8));
    }
    
    static Function<Integer, Integer> incrementBy1 = num -> num+1;
    static Function<Integer, Integer> multiplyBy10 = num -> num*10;
}

在上面的代码中,我们有2个函数接口,一个函数接口递增传入的整数并返回它,第二个函数接口将传入的参数乘以10并返回。现在,如果我们要级联这些功能,即一个接一个地执行一个功能,该怎么办?因此andThen()可以帮助我们解决该用例,因此最初incrementBy1将执行该函数,然后将其结果传递给该multiplyBy10函数,最终结果为90。
 
Bi-Function
BiFunction与Function接口非常相似,唯一的区别是,它接受两个输入参数而不是一个,并产生一个结果。例如,它接受2个类型为T&U的参数,并产生类型为R的结果。
public class App {
    public static void main(String[] args) {
        System.out.println(incrementBy1AndMultiply.apply(8,10));
}

static BiFunction<Integer, Integer, Integer> incrementBy1AndMultiply
            = (num1, num2) -> num2 * (++num1);
}

在上面的代码中,BiFunction接受两个都是Integers的参数,并返回整数类型的结果。这里的BiFunction将第一个参数加1,然后与第二个参数相乘,然后返回结果。在main方法中,我们在调用bifunction时将8作为第一个参数,将10作为第二个参数,因此结果为90。
 
消费者Consumer
消费使用者Consumer是一个函数式接口,它接受单个输入并且不返回任何输出。消费者类似于void函数。它包含两个方法accept&andThen。的接受方法接受类型T的单个参数,andThen是用于组合物中的默认方法。

public class App {
    public static void main(String[] args) {
        greetUser.accept("Vinesh");
    }

    static Consumer<String> greetUser = customer -> 
          System.out.println(
"Hello, " + customer);
}

在上面的代码中,Customer使用String参数,该参数被视为客户名称,此Customer的目的是与客户打招呼。为了调用此Consumer,我们使用accept方法并将名称作为参数传递,因此将其输出Hello, Vinesh。
 
供应商Supplier
Supplier是一个简单的界面,指示此实现是结果的供应商。与消费者相反,供应商可以在您不进行任何输入但返回类型T的对象的地方使用。不要求每次调用供应商都返回新的或不同的结果。供应商只有一个方法get(),没有任何其他默认和静态方法。

public class App {
      public static void main(String[] args) {
      System.out.println(getDBConnectionUrl.get());
      }

static Supplier<String> getDBConnectionUrl = 
    () -> "jdbc://localhost:27017/crud";
}

在上面的代码中,供应商返回一个数据库连接URL,该URL是一个被调用时的字符串。在main方法中,我们使用get方法调用Supplier,并且不发送任何参数。
 
更多:https://github.com/Vinesh-z/Java8_Examples