这里写目录标题

  • 一、Lambda 表达式
  • 1.1 函数式编程思想概述
  • 1.2 Lambda 表达式和匿名内部类的标准格式
  • 1.3 Lambda 表达式的省略模式
  • 1.4 Lambda 表达式的规则
  • 1.5 Lambda 表达式和匿名内部类的区别
  • 二、接口组成更新
  • 2.1 接口组成更新概述
  • 2.2 接口中的默认方法
  • 2.3 接口中的静态方法
  • 2.4 接口中的私有方法
  • 三、方法引用
  • 3.1 方法引用符
  • 3.2 引用方法


一、Lambda 表达式

1.1 函数式编程思想概述

  1. 在数学中,函数就是有输入量和输出量的一套计算方案;
  2. 函数式编程属于“结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。

1.2 Lambda 表达式和匿名内部类的标准格式

匿名内部类中重写 run() 方法的代码分析
• 实例一个线程对象;
• 直接将在传参中实例一个 Runnable 接口;
• 在 Runnable 接口中直接重写 run() 方法;
new Thread( new Runnable(){
	@Override
  public void run() {
      //需要执行的内容
		System.out.println("启动");
	}           
}).start();
Lambda 表达式的代码分析
• 组成 Lambda 表达式的三要数:形参、箭头、代码块;
• 格式 :( 形参列表 ) -> { 代码块 };
new Thread(()->{
	//需要执行的内容
	System.out.println("启动");
}).start();

1.3 Lambda 表达式的省略模式

• 参数类型可以省略,但是不能省略部分参数的类型
useAdd((int x, int y)->{
	return x + y;
});
//化简
useAdd((x,y)->{
	return x + y;
});
• 如果有参数且只有一个,可以省略小括号;
useFly((s)->{
System.out.println("输出:" + s);
});
//只有一个参数的时候进一步化简
useFly(s->{
System.out.println("输出:" + s);
});
• 如果代码块的语句只有一条那么可以省略大括号和分号
useFly(s->{
	System.out.println("输出:" + s);
});
//只有一条执行语句时可以省略大括号和分号
useFly(s -> System.out.println("输出:" + s));
• 如果代码块的语句只有一条返回语句那么省略大括号和分号的同时需要把retuen也省略掉
useAdd((x,y)->{
	return x + y;
});
//如果有return的情况,需要省略return,否则报错
useAdd((x,y)->x-y);

1.4 Lambda 表达式的规则

Lambda 表达式的使用前提:
• 有一个接口;
• 接口中有且只有一个抽象方法;
Lambda 表达式的注意事项:
• 有一个接口且接口中有且只有一个抽象方法;
• 必须有上下文环境,才能推导出 Lambda 对应的接口;
1. 根据局部变量的赋值得知 Lambda 对应的接口:
Runnable r = () -> System.out.println("Lambda表达式");
2. 根据调用的方法得知 Lambda 对应的接口:
new Thread(()-> System.out.println("Lambda表达式")).start();

1.5 Lambda 表达式和匿名内部类的区别

  1. 所支持的类型不同
  • 匿名内部类:可以是接口、抽象类、具体类;
  • Lambda 表达式:只能是接口;
  1. 使用限制不同
  • Lambda 表达式:只能支持重写一个抽象方法的接口;
  • 匿名内部类:可以重写多个抽象方法,但是不能重写部分抽象方法,需要将所有的抽象方法重写;
  1. 实现原理不同
  • 匿名内部类:编译之后产生一个独立的 .class 文件;
  • Lambda 表达式:编译过后不会生成独立的 .class 文件,对应的字节码依附在使用类中;

二、接口组成更新

2.1 接口组成更新概述

接口组成

  • 常量
  • 抽象方法
  • 默认方法(java 8 以后)
  • 静态方法(java 8 以后)
  • 私有方法(java 9 以后)

2.2 接口中的默认方法

接口中默认方法的定义格式:
• 访问修饰符(可省略) + default + 返回值类型 + 方法名( 参数列表 ){ 方法体 }
public interface inter {
   default void interDemo(){
       System.out.println("接口中的默认方法");
   }
}
接口中默认方法的重写:
• 默认方法不是抽象方法可以有方法体,同时不强制重写,若需要重写,重写时去除 default
public class imp implements inter{
   @Override
   public void interDemo() {
       System.out.println("重写后的接口默认方法");
   }
}

2.3 接口中的静态方法

接口中静态方法的定义格式:
• 访问修饰符(可省略) + static + 返回值类型 + 方法名( 参数列表 ){ 方法体 }
public interface inter {
   default static void interDemo(){
       System.out.println("接口中的静态方法");
   }
}
接口中静态方法的调用:
• 静态方法只能通过接口名调用,不能通过实现类调用,也不能重写静态方法
public class interDemo {
   public static void main(String[] args) {
       inter.show3();
   }
}

2.4 接口中的私有方法

接口中私有方法的定义格式:
• private + 返回值类型 + 方法名( 参数列表 ){ 方法体 }
private void use1(){
	System.out.println("私有方法:show");
}
• private + static + 返回值类型 + 方法名( 参数列表 ){ 方法体 }
private static void use2(){
	System.out.println("静态私有方法:show");
}
接口中私有方法的调用:
• 默认方法可以调用私有的静态方法和非静态方法
default void show(){
	use1();
	use2();
}
• 静态方法只可以调用私有的静态方法
static void show5(){
	use2();
}

三、方法引用

3.1 方法引用符

方法引用符 :

  • :: 是方法引用符,它所在的表达式被称为方法引用

示例:

public interface Printable {
   void printString(String s);
}

public class PrintDemo {
   public static void main(String[] args) {
       //lambda 表达式
       usePrintable(s-> System.out.println(s));
		//方法引用符
       usePrintable(System.out::println);
   }
	
   private static void usePrintable(Printable p){
       p.printString("Hello World!!!");
   }
}

3.2 引用方法

引用类方法
• 就是引用类的静态方法; 格式: 类名 + :: + 静态方法;
public interface Printable {
   void printString(String s);
}

public class PrintDemo {
   public static void main(String[] args) {
       //lambda 表达式
       useConverter(s -> Integer.parseInt(s));
       //方法引用符
       useConverter(Integer::parseInt);
   }

   private static void useConverter(Printable p){
       int num = p.Convert("886");
       System.out.println(num);
   }
}
引用对象的实例方法
• 就是引用类的成员方法
• 调用方法的传参类型要一致
• 格式:对象 + :: + 成员方法
public interface Printer {
	public void Convert(String s);
}

public class Printable {
   public void Convert(String s){
       String str = s.toUpperCase();
       System.out.println(s + "->" + str);
   }
}

public class PrintDemo {
   public static void main(String[] args) {
       //lambda 表达式
       usrConvert( s -> System.out.println(s + "->" + s.toUpperCase()));
       Printable p = new Printable();
       //方法引用符
       usrConvert(p::Convert);
   }

   private static void usrConvert(Printer p){
       p.Convert("hello world");
   }
}
引用类的实例方法:
• 就是引用类中的成员方法
• 格式:类名:: 成员方法
public interface MyString {
   String mySubString(String s,int x,int y);
}

public class MyStringDemo {
   public static void main(String[] args) {
       //lambda 表达式
       useMyString((s,x,y)-> s.substring(x,y));
       //方法引用符
       useMyString(String::substring);
   }
   private static void useMyString( MyString my ){
       String s = my.mySubString("HelloWorld",2,5);
       System.out.println(s);
   }
}
引用构造器:
• 就是引用构造方法
• 格式:类名 :: new
public class Student {
   public String name;
   public int age;
   public Student(String name, int age) {
       this.name = name;
       this.age = age;
   }
}

public interface StudentBuilder {
   Student build(String name,int age);
}

public class StudentDemo {
   public static void main(String[] args) {
       //lambda 表达式
       useBuilder((name,age)->new Student(name,age));
       //方法引用符
       useBuilder(Student::new);
   }
   private static void useBuilder(StudentBuilder sb){
       Student s = sb.build("张三",18);
       System.out.println(s.name + "," + s.age);
   }
}