您的位置 首页 java

java函数式编程入门教程

什么是 函数式编程

在介绍函数式编程前,先了解一下平时我们所使用命令式编程,命令式编程是告诉计算机如何一步一步执行编程风格。

比如我们要在一个苹果的对象集合中筛选出颜色为红色的苹果集合。我们需要写以下代码:

  1. 创建存储苹果的集合list
  2. 遍历这个集合
  3. 判断苹果颜色是不是为红色,如果满足条件,加入结果集合
public static List<Apple> getRedAppleDeclarative(List<Apple> apples) {
 List<Apple> results = new ArrayList<> ();
 for (Apple apple : apples) {
 if("red".equals (apple.getColor ())){
 results.add (apple);
 }
 }
 return results;
}
 

那么函数式编程是怎样进行操作的呢?函数式编程类似于我们的sql语句

select * from table where 条件语句
 

只声明我想要什么,以及条件即可

public static List<Apple> getRedApple function al(List<Apple> apples) {
 return apples.stream ().filter (apple -> "red".equals (apple.getColor ())).collect (Collectors.toList ());
}
 

可以看到通过函数式编程大大简化了代码语句,同时如果对函数式结构熟悉的话,很快便可知道这段代码的含义:stream获取apples集合流-filter过滤满足的条件-collect转化为list输出

相比于繁琐的命令式代码,我们函数式编程可以令代码瞬间充满小清新学院风,话不多说,赶紧学习起来以备下次装B之需吧。

通过与 数学函数 的对比加深理解函数式编程

我们都知道数学的中函数思想,比如根据输入x求的y的值,我们用数学函数表示 y=f(x) = x+10, x为输入,以x+10为结果做为条件

那么用java函数式编程风格可以表示为

  Function < Integer ,Integer> function = (x)->{return x+10;};
 

具体调用:

public static Integer calculate(Function<Integer,Integer> function){
 return function.apply (10);
}
public static void main(String[] args) {
 Function<Integer,Integer> function = (x)->{return x+10;};
 Integer result = calculate (function);
}
 

在上面的代码中我们看到,main 函数 中我们定义的function 就是数学中的函数f(x) ,我们把定义好的函数传给方法caculate, caculate中function.apply(10)就相当于我们调用了数学函数f(10).

lambda表达式

我们上面Function接口来表达数据函数f(x) = x+10,这个function就是一个lambda表达式,lamdba表达式由参数箭头和主体构成,基本语法为: (参数)->表达语句

使用lamdba的好处是非常直观,编程者的意图十分明显的表现在lambda表达式里。

java8为lambda是使用提供了一个function包,提供lambda接口,比如上面我们使用过的Function接口,它的定义是

@FunctionalInterface
public interface Function<T, R> {
 /**
 * Applies this function to the given argument.
 *
 * @param t the function argument
 * @return the function result
 */
 R apply(T t);
 default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
 Objects.requireNonNull(before);
 return (V v) -> apply(before.apply(v));
 }
 ...
}
 

可以看到在Function接口中,除了default修饰的方法外,接口中只能有一个方法apply,这也是使用lambda接口的必要条件。他表示给定一个输入T,返回一个输出R,使用lamdba接口时,我们使用表达式来表示实现接口的唯一方法apply()

Function<Integer,Integer> function = (x)->{
 System.out.println("x : "+ String.valueof(x));
 return x+10;
};
 

lambda表达式的另一种表现形式为 lambda方法引用:

lambda方法引用 通过描述符号 :: 来区分类和方法 ::前面是类名;后面是方法,但是不加括号

//lamdba
Predicate<String> q = (String a) -> {
 return a. isEmpty  ();
};
 

使用方法引用来表示的话:

Predicate<String> p = String::isEmpty;
 

具体调用:

public class LambdaTest {
 public static void lambdaFunc(Consumer<String> consumer, Predicate<String> predicate,String test) {
 boolean condition = predicate.test ("");
 if(condition){
 consumer.accept (test);
 }
 }
 public static void main(String[] args) {
 Predicate<String> p = String::isEmpty;
 Consumer<String> c = System.out::println;
 lambdaFunc (c,p,"test");
 }
}
 

上面代码表示如果方法参数test不为空,则进行打印

lambda引用还包括 代替函数式接口和 构造函数 引用

代替函数式接口:

例1:

List<String> testList = Arrays.asList ("a", "b", "A", "B");
// testList.sort ((s1, s2) -> s1.compareToIgnoreCase (s2));
 testList.sort (String::compareToIgnoreCase);
 System.out.println (testList);
 

例2:

public static void main(String[] args) {
// Function<String, Integer> f1 = (String a) -> {return Integer.valueOf (a);};
 Function<String, Integer> f2 = Integer::valueOf;
 Integer result = f2.apply ("2");
 System.out.println (result);
}
 

Function中的 泛型 String代表返回类型,Integer代表输入类型,在lambda引用中会根据泛型来进行类型推断。

构造函数引用:

//方法引用之构造函数引用
public void constructQuote(){
// Supplier<QuoteClass> s1 = () -> new QuoteClass ();
 Supplier<QuoteClass> s2 = QuoteClass::new;
}
 

例子中Supplier 返回一个泛型中类的实例。

以上是函数式编程和lambda的介绍,接下来我们会对java中的stream进行分析,其中涉及的大量的函数式编程的使用。

个人公众号:码农的日常记录

文章来源:智云一二三科技

文章标题:java函数式编程入门教程

文章地址:https://www.zhihuclub.com/184194.shtml

关于作者: 智云科技

热门文章

发表回复

您的电子邮箱地址不会被公开。

网站地图