函数式编程:避免不必要的格式,尽可能的强调做什么事情。
lambda表达式:代替了原来的匿名内部类的写法格式,更加简洁
lambda表达式的基本格式
lambda表达式的基本格式:
() : 代表的是方法中的形式参数
-> : 将参数传递到大括号中
{} :要执行的代码
什么时候使用lambda表达式
调用方法的时候,发现方法中的参数类型是
1,一个接口类型
2,并且这个接口有且仅有一个抽象方法(可以有静态 默认 私有方法)
lambda表达式的入门案例
public class Demo01 {
public static void main(String[] args) {
/* MyRunnable r = new MyRunnable();
Thread t = new Thread®;
t.start();/
//new 的是一个Runnable接口的匿名实现类对象
/ Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(“被执行”);
}
});
t.start();/
/
() : 代表的是方法中的形式参数
-> : 将参数传递到大括号中
{} : 要执行的代码
*/
Thread t2 = new Thread( () -> { System.out.println(“执行任务”); } );
t2.start();
}
}
接口中的抽象方法,没有参数,没有返回值
public interface Eatable {
//没有返回值
//没有参数
public abstract void eat();
}
public class LambdaDemo1 {
public static void main(String[] args) {
mehtod( () -> {
System.out.println(11);
});
//省略写法,省略了一个大括号和分号
mehtod( () ->
System.out.println(11)
);
}
//方法中的参数类型是一个 接口类型
public static void mehtod(Eatable e) {
e.eat();
}
}
lambda表达式代码的执行流程
接口中的抽象方法 有参数,无返回值
public interface Flyable {
//有参数,无返回值
public abstract void fly(String s);
}
public class LambdaDemo2 {
public static void main(String[] args) {
method2( (String abc)->{
System.out.println(abc);
System.out.println(“飞机自驾游”);
});
//省略写法,因为只有一个参数,所以省略了小括号
//大括号不能省略,是因为有多行代码
method2( abc->{
System.out.println(abc);
System.out.println("飞机自驾游");
} );
}
public static void method2(Flyable f){
f.fly(“百亿补贴真的香”);// “百亿补贴真的香” 传到了lambda表达式小括号中的abc
}
}
接口中的抽象方法 有参数,有返回值
public interface Addable {
public abstract int add(int x,int y);
}
public class LambdaDemo3 {
public static void main(String[] args) {
method( (int a, int b) -> {
return a + b; //返回的结果 到 method方法中的result变量
} );
//省略写法,参数的类型省略了,大括号省略了,分号省略了,return省略了
method( ( a, b) -> a+b );
}
public static void method(Addable a) {
int result = a.add(10,20);
System.out.println(result);
}
}
匿名内部类 和 lambda表达式的使用
使用匿名内部类:
在调用方法的时候,参数类型是抽象类,具体类,接口
public abstract class AbsStudent {
public abstract void study();
}
public class Person {
public void jump(){
System.out.println(“tiao”);
}
}
public interface Swiming {
public abstract void swim();
}
public class Test {
public static void main(String[] args) {
//AbsStudent 抽象类的 匿名实现类对象
method(new AbsStudent() {
@Override
public void study() {
System.out.println(“学习”);
}
});
//Person的匿名子类 对象
method2(new Person() {
@Override
public void jump() {
// super.jump();
System.out.println(“跳”);
}
});
//创建Swiming接口的 匿名实现类对象
method3(new Swiming() {
@Override
public void swim() {
System.out.println(“游泳”);
}
});
}
public static void method(AbsStudent absStudent) {
absStudent.study();
}
public static void method2(Person p) {
p.jump();
}
public static void method3(Swiming s){
s.swim();
}
}
使用lambda表达式:
方法中的参数类型是 接口并且接口中有且仅有一个抽象方法
原理不同:
匿名内部类会生成一个xxx.class文件
lambda表达式是在程序运行的时候动态生成,不会直接产生一个.class文件
接口的升级
jdk7 以及之前,接口中只能写 常量以及抽象方法
jdk8,接口中可以写默认方法,以及静态方法
jdk9,接口还可以写私有方法了
public interface DefaultInterface {
//常量
public static final int MAX = 100;
//灰色的部分 是代表可以省略
public abstract void method1();
// 如果在接口中新添加抽象方法,会影响到已经实现当前接口的 实现类
// public abstract void method2();
// 默认方法 不会强制要求 实现类重写(也可以重写)
public default void defaultMethod(){
System.out.println(“默认方法可以有方法体”);
privateMethod();//调用内部的私有方法
}
//静态方法的使用: 接口名字.静态方法名字()
public static void staticMethod(){
System.out.println(“接口中的静态方法”);
privateStaticMethod();//调用内部的静态私有方法
}
//私有方法只能在 内部使用
private void privateMethod(){
System.out.println(“私有方法…”);
}
//私有方法只能在 内部使用
private static void privateStaticMethod(){
System.out.println(“私有静态方法…”);
}
}
//接口的实现类
public class DefaultInterfaceImpl implements DefaultInterface {
@Override
public void method1() {
System.out.println(“method1”);
}
}
//测试类
public class TestInterface {
public static void main(String[] args) {
DefaultInterfaceImpl impl = new DefaultInterfaceImpl();
impl.method1();
impl.defaultMethod();//调用接口中的默认方法
DefaultInterface.staticMethod();//调用静态方法
}
}
引用对象的实例写法
public interface Printable {
public abstract void print(String s);
}
public class LambdaDemo5 {
public static void main(String[] args) {
//lambda表达式: 参数一个,大括号中代码只有一行,代码的特点
//调用一个System.out对象的println()方法,并且将参数传入
method( (String s) -> {
System.out.println(s);
});
method(System.out::println);
ArrayList list = new ArrayList<>();
//lambda表达式: 参数一个,大括号中代码只有一行,代码的特点
//调用一个list对象的add()方法,并且将参数传入
method( (String s) -> {
list.add(s);
});
//引用对象的实例方法
method( list::add );
}
public static void method(Printable p) {
p.print(“Java从入门到放弃”);
}
}
引用类方法
public interface Convert {
public abstract int conver(String a);
}
public class lambdaDemo6 {
public static void main(String[] args) {
//大括号中代码只有一行,并且是调用了类的静态方法,
//并且参数可以传入到方法中,此时就可以使用引用类方法的格式
method((String a) -> {
return Integer.parseInt(a);
});
//引用类方法
method( Integer::parseInt );
}
public static void method(Convert c) {
int result= c.conver(“100”);
System.out.println(result);
}
}
引用类的实例方法
public interface SubStringInterface {
String sub(String str,int start,int end);
}
public class lambdaDemo7 {
public static void main(String[] args) {
//小括号中参数有多个,大括号里使用第一个参数作为对象
//然后调用方法,方法需要的参数正好和小括号剩下的参数对应上
method((String str, int start, int end) -> {
return str.substring(start,end);
});
//类的实例写法
method(String::substring);
}
public static void method(SubStringInterface s) {
String result = s.sub(“入门到精通”, 0, 2);
System.out.println(result);
}
}
引用构造器写法
public interface StudentBuilder {
Student build(String name,int age);
}
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class LambdaDEmo8 {
public static void main(String[] args) {
//大阔号中只有一行new 对象的操作,刚好构造方法需要的参数
//和小括号中的参数对应上
method((String name, int age) -> {
return new Student(name,age);
});
//引用构造器写法
method(Student::new);
}
public static void method(StudentBuilder s) {
Student stu = s.build(“张三”, 100);
System.out.println(stu.getAge());
}
}