面向对象的思想:
做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
函数式编程思想:
只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程
Java8引入了Lambda表达式之后,Java也开始支持函数式编程。
Lambda表达式不是Java最早使用的,很多语言就支持Lambda表达式,例如:C++,C#,Python,Scala等。如果有Python或者Javascript的语言基础,对理解Lambda表达式有很大帮助,可以这么说lambda表达式其实就是实现SAM接口的语法糖,使得Java也算是支持函数式编程的语言。Lambda写的好可以极大的减少代码冗余,同时可读性也好过冗长的匿名内部类。
“语法糖”是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实 底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,Java中的Lambda可以被当做是匿名内部 类的“语法糖”,但是二者在原理上是不同的。
要实现这个lambda必须满足语法糖的要求即:接口中只有一个抽象方法需要实现,当然该接口可以包含其他非抽象方法。
@FunctionalInterface 注解,推荐加在自定义的函数式接口上,当然java8有很多给定的函数式接口。消费型、供给型、判断型、功能型 ,这几大类可以满足日常开发的需求,但是并不是绝对的你也可以自定义函数式接口,不过最好加上开头的那个注解。
lambda表达式的语法:
(形参列表) -> {Lambda体}
这个不是最简的还可以优化:
当{Lambda体}中只有一句语句时,可以省略{}和{;}
当{Lambda体}中只有一句语句时,并且这个语句还是一个return语句,那么return也可以省略,但是如果{;}没有省略的话,return是不能省略的
(形参列表)的类型可以省略
当(形参列表)的形参个数只有一个,那么可以把数据类型和()一起省略,但是形参名不能省略
当(形参列表)是空参时,()不能省略
public class ZuoYe1 {//自定义的函数式接口,用lambda进行计算
public static void main(String[] args) {
getProduct(1,2,(a,b)->a+b);
getProduct(1,2,(a,b)->a-b);
getProduct(1,2,(a,b)->a*b);
getProduct(1,2,(a,b)->a/b);
getProduct(1,2,(a,b)->a&b);
getProduct(1,2,(a,b)->a<<b);
}
public static void getProduct(int a , int b ,IntCalc tools){
System.out.println(tools.cal(a, b));
}
}
@FunctionalInterface//这个注解在编译时会自动检查该接口中是否只有一个抽象方法
interface IntCalc{
int cal(int a , int b);
}
package com.thekingqj.day27;
import java.util.Arrays;
import java.util.Date;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.junit.Test;
public class Test1 {//调用给定的函数式接口实现lambda表达式
@Test
public void Test2(){
Consumer<String> con=new Consumer<String>() {
@Override
public void accept(String t) {
System.out.println("一脸懵逼");
}
};
con.accept("");
Consumer<String> con1=t->System.out.println(t);
con1.accept("132456897wesdrfghj");
BiConsumer<String , Integer> bic=new BiConsumer<String, Integer>() {
@Override
public void accept(String t, Integer u) {
System.out.println(t.length()>u);
}
};
bic.accept("132465", 2);
BiConsumer<String, Integer>bic1=(t,u)->System.out.println(t.length()>u);
bic1.accept("465789", 5);
Supplier<Date>su=()-> new Date();
Runnable r=System.out::println;
r.run();
System.out.println(su.get());
String[] arr = {"Hello","java","chai"};
// Arrays.sort(arr, (s1,s2) -> s1.compareToIgnoreCase(s2));
//用方法引用简化
/*
* Lambda表达式的形参,第一个(例如:s1),正好是调用方法的对象,剩下的形参(例如:s2)正好是给这个方法的实参
*/
Arrays.sort(arr, String::compareToIgnoreCase);
System.out.println(Arrays.toString(arr));
}
}
方法引用,构造器引用,数组引用:目的的更加简化lambda表达式
1. 方法引用
条件:
接口中只有一个方法
接口中的抽象方法实现只有一行代码
这一行代码是方法调用
抽象方法的参数列表要和调用方法的参数列表保持一致
或者 调用方法的调用者是抽象方法的第一个参数,抽象方法的剩余参数和调用方法的参数保持一致
对象.普通方法 对象::普通方法名称
Consumer<String> con2=System.out::println;
类名.静态方法 类名::静态方法名
BiFunction<Double, Double, Integer> bifun1=Double::compare;
类名::普通方法
BiFunction<String, String, Boolean> bifun1=String::contains;
2. 构造器引用
条件:
接口中只有一个方法
接口中的抽象方法实现只有一行代码
这行代码必须是创建对象的代码
创建的对象类型必须和返回值类型一致
抽象方法的参数列表和构造器的参数列表保持一致
类名::new
Supplier<String> su=String::new;
Function<Integer, StringBuffer> fun=StringBuffer::new;
3. 数组引用
条件:
接口中只有一个方法
接口中的抽象方法实现只有一行代码
这行代码必须是创建数组的代码
创建的数组类型必须和返回值类型一致
参数必须是数组的长度
数组类型[]::new
Function<Integer, String[]> fun=String[]::new;
消费型接口
消费型接口的抽象方法特点:有形参,但是返回值类型是void
接口名 | 抽象方法 | 描述 |
---|---|---|
Consumer<T> | void accept(T t) | 接收一个对象用于完成功能 |
BiConsumer<T,U> | void accept(T t, U u) | 接收两个对象用于完成功能 |
DoubleConsumer | void accept(double value) | 接收一个double值 |
IntConsumer | void accept(int value) | 接收一个int值 |
LongConsumer | void accept(long value) | 接收一个long值 |
ObjDoubleConsumer<T> | void accept(T t, double value) | 接收一个对象和一个double值 |
ObjIntConsumer<T> | void accept(T t, int value) | 接收一个对象和一个int值 |
ObjLongConsumer<T> | void accept(T t, long value) | 接收一个对象和一个long值 |
供给型接口
这类接口的抽象方法特点:无参,但是无返回值
接口名 | 抽象方法 | 描述 |
---|---|---|
Supplier<T> | T get() | 返回一个对象 |
BooleanSupplier | boolean getAsBoolean() | 返回一个boolean值 |
DoubleSupplier | double getAsDouble() | 返回一个double值 |
IntSupplier | int getAsInt() | 返回一个int值 |
LongSupplier | long getAsLong() | 返回一个long值 |
判断型接口
这里接口的抽象方法特点:有参,但是返回值类型是boolean结果。
接口名 | 抽象方法 | 描述 |
---|---|---|
Predicate<T> | boolean test(T t) | 接收一个对象 |
BiPredicate<T,U> | boolean test(T t, U u) | 接收两个对象 |
DoublePredicate | boolean test(double value) | 接收一个double值 |
IntPredicate | boolean test(int value) | 接收一个int值 |
LongPredicate | boolean test(long value) | 接收一个long值 |
功能型接口
这类接口的抽象方法特点:既有参数又有返回值
接口名 | 抽象方法 | 描述 |
---|---|---|
Function<T,R> | R apply(T t) | 接收一个T类型对象,返回一个R类型对象结果 |
UnaryOperator<T> | T apply(T t) | 接收一个T类型对象,返回一个T类型对象结果 |
DoubleFunction<R> | R apply(double value) | 接收一个double值,返回一个R类型对象 |
IntFunction<R> | R apply(int value) | 接收一个int值,返回一个R类型对象 |
LongFunction<R> | R apply(long value) | 接收一个long值,返回一个R类型对象 |
ToDoubleFunction<T> | double applyAsDouble(T value) | 接收一个T类型对象,返回一个double |
ToIntFunction<T> | int applyAsInt(T value) | 接收一个T类型对象,返回一个int |
ToLongFunction<T> | long applyAsLong(T value) | 接收一个T类型对象,返回一个long |
DoubleToIntFunction | int applyAsInt(double value) | 接收一个double值,返回一个int结果 |
DoubleToLongFunction | long applyAsLong(double value) | 接收一个double值,返回一个long结果 |
IntToDoubleFunction | double applyAsDouble(int value) | 接收一个int值,返回一个double结果 |
IntToLongFunction | long applyAsLong(int value) | 接收一个int值,返回一个long结果 |
LongToDoubleFunction | double applyAsDouble(long value) | 接收一个long值,返回一个double结果 |
LongToIntFunction | int applyAsInt(long value) | 接收一个long值,返回一个int结果 |
DoubleUnaryOperator | double applyAsDouble(double operand) | 接收一个double值,返回一个double |
IntUnaryOperator | int applyAsInt(int operand) | 接收一个int值,返回一个int结果 |
LongUnaryOperator | long applyAsLong(long operand) | 接收一个long值,返回一个long结果 |
BiFunction<T,U,R> | R apply(T t, U u) | 接收一个T类型和一个U类型对象,返回一个R类型对象结果 |
BinaryOperator<T> | T apply(T t, T u) | 接收两个T类型对象,返回一个T类型对象结果 |
ToDoubleBiFunction<T,U> | double applyAsDouble(T t, U u) | 接收一个T类型和一个U类型对象,返回一个double |
ToIntBiFunction<T,U> | int applyAsInt(T t, U u) | 接收一个T类型和一个U类型对象,返回一个int |
ToLongBiFunction<T,U> | long applyAsLong(T t, U u) | 接收一个T类型和一个U类型对象,返回一个long |
DoubleBinaryOperator | double applyAsDouble(double left, double right) | 接收两个double值,返回一个double结果 |
IntBinaryOperator | int applyAsInt(int left, int right) | 接收两个int值,返回一个int结果 |
LongBinaryOperator | long applyAsLong(long left, long right) | 接收两个long值,返回一个long结果 |