网站首页 > java教程 正文
什么是函数式编程
在介绍函数式编程前,先了解一下平时我们所使用命令式编程,命令式编程是告诉计算机如何一步一步执行编程风格。
比如我们要在一个苹果的对象集合中筛选出颜色为红色的苹果集合。我们需要写以下代码:
- 创建存储苹果的集合list
- 遍历这个集合
- 判断苹果颜色是不是为红色,如果满足条件,加入结果集合
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> getRedAppleFunctional(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进行分析,其中涉及的大量的函数式编程的使用。
个人公众号:码农的日常记录
猜你喜欢
- 2024-10-07 python函数式编程(python函数经典例程)
- 2024-10-07 JavaScript 的函数式编程与面向对象编程区别在哪?
- 2024-10-07 函数式编程:Python和Java的实现方式有哪些?
- 2024-10-07 函数式编程与命令式编程的区别以及函数式编程不需要锁
- 2024-10-07 前端同学如何函数式编程?(前端函数式编程和响应式编程)
- 2024-10-07 java8精华-函数式编程-Function (五)
- 2024-10-07 Java函数式编程实战:Consumer、Predicate和Supplier的使用指南
- 2024-10-07 java码农福音:函数式编程和lambda表达式
- 2024-10-07 深入理解Java中的Lambda表达式和函数式编程的关系
- 2024-10-07 Java 的函数式接口(必懂知识点!)(jdk1.8函数式接口)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)