函数式编程思维概述
在数学中,函数就是有输入量、输出量的一套计算计划,也就是“拿数据做操作”
面向对象思维强调“必须通过对象的模式来做事件”
函数式思维则尽量疏忽面向对象的简单语法:“强调做什么,而不是以什么模式去做”
Lambda表达式就是函数式思维的体现
体验Lambda表达式
需要:启动一个线程,在控制台输入一句话:多线程程序启动了
形式一
- 定义一个类MyRunnable实现Runnable接口,重写run()办法
- 创立MyRunnable类的对象
- 创立Thread类的对象,把MyRunnable的对象作为结构参数传递
- 启动线程
采纳了实现类的形式实现需求
public class MyRunnable implements Runnable{ private int tickets = 100; //重写run办法 实现卖票 @Override public void run(){ sout("多线程程序启动了"); } } //主程序LambdaDemo //创立MyRunnable对象 MyRunnable my = new MyRunnable(); //创立Thread类的对象,把MyRunnable对象作为构造方法的参数 Thread t1 = new Thread(my); //启动线程<p style="color:transparent">来源gao!%daima.com搞$代*!码网</p> t1.start();
形式二
采纳了匿名外部类形式改良
new Thread(new Runnable(){ @Override public void run(){ sout("多线程程序启动了"); } }).start();
形式三
采纳了Lambda表达式形式改良
new Thread( () -> { sout("多线程程序启动了"); } ).start();
Lambda表达式的规范格局
Lambda表达式的格局:
- 格局:(形式参数)->{代码块}
- 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
- ->:由英文中画线和大于符号组成,固定写法。代表指向动作
-
代码块:是咱们具体要做的事件,也就是以前咱们写的办法体内容
Lambda表达式的练习
Lambda表达式应用前提
- 有一个接口
- 接口中有且仅有一个形象办法
练习1:
形式一
采纳了实现类的形式实现需求
//定义一个接口 public interface Eatable{ void eat();//接口中有且仅有一个形象办法 } //定义一个类实现这个接口 public class EatablleImpl implements Eatable{ @Override public void eat(){ sout("一天一苹果"); } } //主程序 //定义的其中一个办法 private static void useEatable(Eatable e){ e.eat(); } //在主办法中调用这个办法 //创立接口的对象,通过多态的形式 Eatable e = new EatablleImpl(); useEatable(e);
形式二
采纳了匿名外部类的形式实现需求
useEatable(new Eatable (){ @Override public void eat(){ sout("一天一苹果"); } });
形式三
采纳了Lambda表达式形式改良
useEatable( () -> { sout("一天一苹果"); } );
练习2:
//定义一个接口 public interface Flyable{ void fly(String s);//接口中有且仅有一个形象办法 } //主程序 //定义的其中一个办法 private static void useFlyable(Flyable f){ f.fly(s:"风和日丽"); } //在主办法中调用这个办法 //创立接口的对象,通过多态的形式 Eatable e = new EatablleImpl(); useEatable(e);
形式一
采纳了匿名外部类的形式实现需求
useFlyable (new Flyable (){ @Override public void fly(String s){ sout(s); sout("飞机自驾游") } });
形式二
采纳了Lambda表达式形式改良
useFlyable( (String s) -> { sout(s); sout("飞机自驾游") } );
练习3:
//定义一个接口 public interface Addable{ int add(int x,int y);//接口中有且仅有一个形象办法 } //主程序 //定义的其中一个办法 private static void useAddable(Addable a){ int sum = a.add(x:10,y:10); sout(sum); } //在主办法中调用这个办法 //创立接口的对象,通过多态的形式
采纳了Lambda表达式形式改良
useAddable( (int x,int y) -> { return x+y;//这是具体的实现 不看办法名,应该看具体的实现 } );
Lambda表达式的省略模式
//定义一个接口 public interface Addable{ int add(int x,int y); } //定义一个接口 public interface Flyable{ void fly(String s); } //测试类 useAddable( (int x,int y) -> { return x+y;//这是具体的实现 不看办法名,应该看具体的实现 } ); //参数的类型能够省略 然而又多个参数的状况下,不能只省略一个,要么都省略,要么都不省略 useAddable( (x,y) -> { return x+y;//这是具体的实现 不看办法名,应该看具体的实现 } ); useFlyable( (String s) -> { sout(s); } ); //省略掉类型 useFlyable( (s) -> { sout(s); } ); //如果参数有且仅有一个,小括号也能够省略 useFlyable( s -> { sout(s); } ); //如果代码块的语句只有一条,能够省略大括号和分号 如果有return,return也要省略掉, useFlyable( s -> sout(s)); //如果有return,return也要省略掉,只针对代码块语句只有一条的状况下 useAddable( (x,y) -> x+y ); //定义的其中一个办法 private static void useFlyable(Flyable f){ f.fly(s:"风和日丽"); } //定义的其中一个办法 private static void useAddable(Addable a){ int sum = a.add(x:10,y:10); sout(sum); }
省略规定:
- 参数的类型能够省略 然而有多个参数的状况下,不能只省略一个,要么都省略,要么都不省略
- 如果参数有且仅有一个,小括号也能够省略
- 如果代码块的语句只有一条,能够省略大括号和分号 如果有return,return也要省略掉
Lambda表达式的注意事项
//定义一个接口 public interface Inter{ void show(); //在接口中增加一个办法 //void method(); } //定义的其中一个办法 应用这个接口作为参数的办法 private static void useInter(Inter i){ i.show(); } //主办法的程序 //应用Lambda必须要有接口,并且要求接口中有且仅有一个形象办法 useFlyable( (String s) -> { sout("好好学习"); } ); //化简 useFlyable( s -> sout("好好学习") ); //应用Lambda必须有上下文环境,能力推导出Lambda对应的接口 new Thread(new Runnable(){ @Override public void run(){ sout("匿名外部类"); } }).start(); Runnable r = () -> sout("好好学习");//依据局部变量的类型来推导lambda表达式对应的接口 new Thread(r).start(); //优化 new Thread(() -> sout("好好学习")).start();
注意事项:
Lambda表达式和匿名外部类的区别
//定义一个接口 public interface Inter{ void show(); } //定义一个类 public abstract class Animal{ public abstract void method();//无参无返回值 } //定义一个类 public class Student{ public void study(){ sout("爱生存"); } } //测试类 //在测试类里定义方法调用 private static void useStudent(Student s){ s.study(); } private static void useAnimal(Animal a){ a.method(); } private static void useInter(Inter i){ i.show(); } //主函数 //先写匿名外部类的 useInter (new Inter (){ @Override public void show(){ sout("接口") } }); useAnimal (new Animal (){ @Override public void method(){ sout("抽象类") } }); useStudent (new Student (){ @Override public void study(){ sout("具体类") } }); //用Lambda表达式调用 useInter(() -> sout("接口")); useAnimal(() -> sout("抽象类"));//这个报错 useStudent(() -> sout("具体类"));//这个也报错
匿名外部类输入
接口中存在多个办法时,应用匿名外部类能够调用办法
Laambda表达式输入