函数式编程思想:不在乎过程的方式,不在乎对象是那个,只在乎返回结果(重结果,轻过程)
面向对象思想:找一个对象,去做事情(万物皆对象)
转变过程:
以多线程为例:
为了获取Runnable
接口的实现对象,为该接口定义一个实现类`RunnableImpl,设置线程任务
public class RunnableImpl implements Runnable {
@Override
public void run() {
System.out.println("多线程任务执行!");
}
}
然后创建该实现类的对象作为Thread
类的构造参数:
public class Demo03ThreadInitParam {
public static void main(String[] args) {
Runnable task = new RunnableImpl();
new Thread(task).start();
}
}
这个RunnableImpl
类只是为了实现Runnable
接口而存在的,而且仅被使用了唯一一次,所以使用匿名内部类的语法即可省去该类的单独定义,即匿名内部类:
public class Demo04ThreadNameless {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("多线程任务执行!");
}
}).start();
}
}
public class Demo04ThreadNameless {
public static void main(String[] args) {
new Thread(() -> System.out.println("多线程任务执行!")).start();
}
}
你会发现使用了lambda表达式的书写代码简约而不简单
Lambda省去面向对象的条条框框,格式由3个部分组成:
Lambda表达式的标准格式为:
(参数类型 参数名称) -> { 代码语句 }
格式说明:
->
是新引入的语法格式,代表指向动作。Lambda的语法非常简洁,完全没有面向对象复杂的束缚。但是使用时有几个问题需要特别注意:
Runnable
、Comparator
接口还是自定义的接口,只有当接口中的抽象方法存在且唯一时,才可以使用Lambda。备注:有且仅有一个抽象方法的接口,称为“函数式接口”。
@FunctionalInterface注解
与 @Override 注解的作用类似,Java 8中专门为函数式接口引入了一个新的注解: @FunctionalInterface 。该注
解可用于一个接口的定义上:一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
@FunctionalInterface
public interface MyFunctionalInterface {
void myMethod();
}
java.util.function.Supplier 接口仅包含一个无参的方法: T get() 。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。
作用:生产型接口,指定接口的泛型是什么,就生产什么类型的数据
java.util.function.Consumer 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,
其数据类型由泛型决定。
抽象方法:accept
Consumer 接口中包含抽象方法 void accept(T t) ,意为消费一个指定泛型的数据。
作用:消费性接口,泛型执行什么类型,就可以使用accept消费什么类型的数据
默认方法:andThen
如果一个方法的参数和返回值全都是 Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作,
然后再做一个操作,实现组合。而这个方法就是 Consumer 接口中的default方法 andThen 。下面是JDK的源代码:
Consummer con1;
Consummer con2;
String s="hello";
con1.accept(s);
con2.accept(s);
con1.andThen(con2).accept(s);
作用:对某种类型的数据进行判断,从而得到一个boolean值结果。
java.util.function.Predicate 接口。
抽象方法:test
Predicate 接口中包含一个抽象方法: boolean test(T t) 。用于条件判断的场景:
默认方法:and ,有false则false
既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 Predicate 条件使用“与”逻辑连接起来实
现“并且”的效果时,可以使用default方法 and 。
p1.and(p2).test(S)
p1.test(s)&&p2.test(s)
默认方法:or 有true则true
与 and 的“与”类似,默认方法 or 实现逻辑关系中的“或”。
默认方法:negate 有true则false,有false则true
“与”、“或”已经了解了,剩下的“非”(取反)也会简单。
作用:接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。
java.util.function.Function
抽象方法:apply
Function 接口中最主要的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。
使用的场景例如:将 String 类型转换为 Integer 类型。
默认方法:andThen
Function 接口中有一个默认的 andThen 方法,用来进行组合操作