08 Lambda
案例
/**
* 1,设未知数 λ 定义一个接口只有一个抽象方法
* 2,未知数赋值 λ 赋值需要函数结构一样(参数列表与返回值)
* a,重写方法体 new 接口{
* @Override
* 重写接口中的方法。
* };
* b,a方法的简写(参数列表)->{重写方法} 因为名字以及返回值都已经确定 所以简写 删除重复的部分。
* c,赋值找到方法 赋予值 类::类中方法 对象::对象中的方法
* 3,使用 需要将 λ 传入并给其值从而得到相应的结果。 即某个方法调用
* Created by ppliang on 2020/10/27 19:06
*/
interface Strategy {
String approach(String msg);
}
class Soft implements Strategy {
@Override
public String approach(String msg) {
return msg.toLowerCase() + "?";
}
}
class Unrelated {
static String twice(String msg) {
return msg + " " + msg;
}
}
public class Strategize {
Strategy strategy;
String msg;
public Strategize(String msg) {
strategy = new Soft();
this.msg = msg;
}
void communicate() {
System.out.println(strategy.approach(msg));
}
void changStrategy(Strategy strategy) {
this.strategy = strategy;
}
//直接看 主方法体
public static void main(String[] args) {
Strategy[] strategies = {
// a,重写方法体 new 接口
new Strategy() {
@Override
public String approach(String msg) {
return msg.toUpperCase() + "!";
}
},
// b,a方法的简写(参数列表)->{重写方法} 因为名字以及返回值都已经确定 所以简写 删除重复的部分。
msg -> msg.substring(0, 5),
//c,赋值找到方法 赋予值 类::类中方法 对象::对象中的方法
Unrelated::twice
};
Strategize s = new Strategize("Hello there");
s.communicate();
for (Strategy strategy : strategies) {
//3,使用 需要将 λ 传入并给其值从而得到相应的结果。 即某个方法调用
s.changStrategy(strategy);
s.communicate();
}
strategies[0].approach("我也可以直接接口对象调用 但不会显示哦 因为我只会执行重写后的方法!");
}
}
Lambda 表达式是使用最小可能语法编写的函数定义:
- Lambda 表达式产生函数,而不是类。 在 JVM(Java Virtual Machine,Java 虚拟机)上,一切都是一个类,因此在幕后执行各种操作使 Lambda 看起来像函数 —— 但作为程序员,你可以高兴地假装它们“只是函数”。
- Lambda 语法尽可能少,这正是为了使 Lambda 易于编写和使用。
四大内置函数式接口
你是不是感觉设未知数λ很麻烦,放心 java把常见的未知数都设好了
消费型、供给型、函数型、断定型
消费型接口 Comsumer void accept(T t)
供给型接口 Supplier T get()
函数型接口 Function<T,R> R apply(T t)
断定型接口 Predicate boolean test(T t)
构造器引用
Supplier<Student> supplier=()->new Student();
Supplier<Student> supplier2= Student::new;
需要调用的构造器的参数列表要与函数式接口中抽象方法参数列表保持一致。
常用操作
lambda实现Runnable接口中的run方法
new Thread(new Runnable() {
public void run() {
System.out.println("我重写run方法");
}
}).start();
new Thread(
() -> System.out.println("我重写run方法比你简单")
).start();
//接口 GO go方法
interface Go{
static void go(){
System.out.println("我藏起来重写了!");
}
}
new Thread(Go::go).start();
未绑定的方法引用
未绑定的方法引用是指没有关联对象的普通(非静态)方法。 使用未绑定的引用时,我们必须先提供对象:
接口 接口方法=类对象:对象方法
当接口方法中有一个参数 而对象方法中无参数
接口参数中的方法可以接受 对象。则可以等效 对象与方法的传入。
class X {
String f() {
return "X::f()"; }
}
interface MakeString {
String make();
}
interface TransformX {
String transform(X x);
}
public class UnboundMethodReference {
public static void main(String[] args) {
// MakeString ms = X::f; // [1]
TransformX sp = X::f;
X x = new X();
System.out.println(sp.transform(x)); // [2]
System.out.println(x.f()); // 同等效果
}
}
构造函数引用
MakeNoArgs mna = Dog::new; // [1]
Make1Arg m1a = Dog::new; // [2]
Make2Args m2a = Dog::new; // [3]
Dog dn = mna.make();
Dog d1 = m1a.make("Comet");
Dog d2 = m2a.make("Ralph", 4);
花里花哨
lambda写递归
public class Test05 {
static Function<Integer, Integer> function;
public static void main(String[] args) {
function = n -> n == 0 ? 1 : n * function.apply(n - 1);
for (int i = 0; i <= 10; i++) {
System.out.println(function.apply(i));
}
}
}