是相较于 命令式编程 的一种编程范式;
是一种如何 搭建应用程序 的方法论,不是一种具体的技术;
具体的,能够熟练应用Stream流相关的API ,lamdba 表达式 到工作中,就说明你会函数式编程
函数式编程:关注做什么,说白了,内置函数库已经将需要的功能实现好了,直接用
命令式编程:关注怎么做,具体实现细节需要我们自己代码编写
为什么要使用函数式编程:
使用 lambda 能够使得代码更加的简洁
Lambda 表达式
===========
其实也是一个匿名函数,它不去关心接口名,方法名,参数名,而是关心参数类型,参数个数,返回值信息
形式上: (i) -> i *2
即:参数列表 -> 函数体
本质:返回了一个 实现指定接口的对象实例
那么,是不是任意接口都是可以的呢?当然不是这样哈,这个接口必须是函数接口(java8新引入的接口特性)。
总结
==
Lambda 表达式在Java 语言中引入了一个新的语法元 素和操作符。这个操作符为 “->” , 该操作符被称为 Lambda 操作符或剪头操作符。
它将 Lambda 分为 两个部分:
左侧:指定了 Lambda 表达式需要的所有参数
右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能。
Jdk8 接口新特性
===========
1.函数接口:@FunctionalInterface ,这个接口有且仅有一个 要实现的非静态方法,函数接口包含了多个未实现的方法的话,就会报错。
现在回头想想:箭头左边是函数接口的参数 ,箭头右边是这个函数接口的具体实现
2. 默认实现的方法
需要注意,函数接口并不是只能有一个方法,可以是
多个默认实现了方法 + 1个未实现的非静态方法 的形式 ,如下:
@FunctionalInterface
interface Interface1{
// 1个未实现的非静态方法
int doubleNum(int i);
// 默认实现的方法
default int add(int x ,int y){
return x + y;
}
}
- 在 函数接口多重继承的时候,如果出现 同名的默认实现的方法,这个时候需要指定具体是哪个类的默认方法。
注意学习:接口的默认方法,如List
Java8 内置的函数接口
=============
java已经帮我们定义好了一些常用的函数接口,就不用我们自己去定义了,我们仅关注自己的实现逻辑即可;同时函数接口也支持链式编程
定义更少的接口,可以更加灵活的操作
那么常见内置的函数接口有哪些呢?
Java8之Predicate函数
=================
Predicate 一个函数式接口,属于java.util.function包,主要用来对输入的对象按照指定的条件进行过滤。
大家不要对这种函数式接口抱有太大的畏惧心理,要我说,如果没有对应的场景,他就只是一堆代码而已,都是纸老虎!
Predicate就是一个接口,里面有且仅有一个抽象方法test方法:
boolean test(T t);
T是你传进去的参数,可以是任意类型,返回的是一个布尔值。意思就是:你给我一个值,我告诉你对不对?
这是一种操作,一种回调。它不是一种有方法体的函数,也就没有逻辑,逻辑是要你自己补充的。
我们先来一个简单的例子,有一个Person类,有name和sex字段,如果sex=男,我就输出“男孩”,简单吧!
class Person{
public Person(String name, String sex) {
this.name = name;
this.sex = sex;
}
String name;
String sex;
}
然后去判断是不是男的
Person jack = new Person(“jack”,“男”);
if(“男”.equals(jack.sex)){
System.out.println(jack.name + “是男的!”);
}
答案:jack是男的!
那么,我们如何用Predicate来实现这个场景呢?
public void test2(){
Person jack = new Person(“jack”,“男”);
/** 新建一个判断是否为Boy的匿名子类对象,别忘了全部加泛型否则会报错 * */
Predicate PredicateBody = new Predicate() {
@Override
public boolean test(Person o) {
return “男”.equals(o.sex);
}
};
if(PredicateBody.test(jack)){
System.out.println(jack.name + “是男的!”);
}
}
PredicateBody的生成方式可以换成Lamda,看起来更简洁一些。
IDEA还有贴心的提示,这也太牛了吧!
Predicate PredicateBody = o -> “男”.equals(o.sex);
什么,你还觉得不够爽?之前学了匿名子类对象的初始化,忍不住要试试?
行啊,试试就试试!
看代码:
if(new Predicate(){
@Override
public boolean test(Person person) {
return “男”.equals(person.sex);
}
}.test(jack)){
System.out.println(jack.name + “是男的!”);
}
如果这种Predicate对象其他方法也需要用怎么办?有一个技巧就是单独做一个方法,返回这种独有的Predicate对象。
/** 好耶!做成static任何地方想用就用啦! * */
public static Predicate PredicateBody (){
return new Predicate(){
@Override
public boolean test(Person person) {
return “男”.equals(person.sex);
}
};
}
然后是用的地方:
Person jack = new Person(“jack”,“男”);
if(PredicateBody().test(jack)){
System.out.println(jack.name + “是男的!”);
}
最后附上Predicate源码:
/*
-
Copyright © 2010, 2013, Oracle and/or its affiliates. All rights reserved.
-
ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package java.util.function;
import java.util.Objects;
/**
-
Represents a predicate (boolean-valued function) of one argument.
-
This is a functional interface
-
whose functional method is {@link #test(Object)}.
-
@param the type of the input to the predicate
-
@since 1.8
*/
@FunctionalInterface
public interface Predicate {
/**
-
Evaluates this predicate on the given argument.
-
@param t the input argument
-
@return {@code true} if the input argument matches the predicate,
-
otherwise {@code false}
*/
boolean test(T t);
/**
-
Returns a composed predicate that represents a short-circuiting logical
-
AND of this predicate and another. When evaluating the composed
-
predicate, if this predicate is {@code false}, then the {@code other}
-
predicate is not evaluated.
-
Any exceptions thrown during evaluation of either predicate are relayed
-
to the caller; if evaluation of this predicate throws an exception, the
-
{@code other} predicate will not be evaluated.
-
@param other a predicate that will be logically-ANDed with this
-
predicate
-
@return a composed predicate that represents the short-circuiting logical
-
AND of this predicate and the {@code other} predicate
-
@throws NullPointerException if other is null
*/
default Predicate and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);