• 匿名内部类和Lambda表达式


    匿名内部类

    定义: 匿名内部类是没有名称的内部类
    说明: 在调用包含有接口类型参数的方法时,通常为了简化代码,可以直接通过匿名内部类的形式传入一个接口类型参数,在匿名内部类中直接完成方法的实现。

    /*
    *匿名内部类的前提
    *必须是类或者接口
    *
    *格式:
    *
    *new 类名/接口名(){
    *重写抽象方法
    *}
    */
    public class Demo01 {
    	public static void main(String[] args) {
    		//整体等效于:是Animal父类的子类对象
    		//new Animal(){
    		//  @Ovrride
    		//  public void eat() {
    		//     System.out.println("我吃饭");
    		//  }
    		//};
    		
    		//方法一
    	    new Animal(){
    		  @Ovrride
    		  public void eat() {
    		    System.out.println("我吃饭");
    		 }
    		}.eat();
    
            //方法二
            //通过匿名内部类访问局部变量.在JDK版本之前,必须加final关键字
            String name = "路西法";
            
            Animal a = new Animal(){
    		  @Ovrride
    		  public void eat() {
    		    System.out.println(name+"在吃饭");
    		 }
    		};
    		a.eat();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    public abstract class Animal {
    	public abstract void eat();
    }
    
    • 1
    • 2
    • 3
    public class Dog extends Animal{
    	@Ovrride
    	public void eat() {
    		System.out.println("狗吃肉");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class Demo02 {
    	public static void main(String[] args) {
    	  function(
    	   	new Inner() {
    		  @Ovrride
    		  public void method() {
    		    Sysytem.out.println("我重写后的menthod方法");
    		    }
    		}.method();
    	   );
    	}
    
        public static void function(Inter i) {
            i.method();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    public interface Inter {
    	public abstract void method();
    }
    
    • 1
    • 2
    • 3

    Lambda表达式

    Lambda表达式介绍
    Java8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。通过Lambda表达式,可以替代我们以前经常写的匿名内部类来实现接口。Lambda表达式本质是一个匿名函数


    Lambda表达式语法
    (int a,int b) -> (return a+b);
    本质是一个函数;

    一般的函数类似如下:

    int add(int a,int b) {
    	return a+b;
    }
    
    • 1
    • 2
    • 3

    有返回值,方法名,参数列表,方法体

    Lambda表达式函数的话,只有参数列表方法体
    (参数列表) -> {方法体}
    说明:
    (): 用来描述参数列表
    {}: 用来描述方法体
    ->: Lambda运算符,可以叫做箭头符号,或者goes to

    案例;接口方法参数,无参,单个参数,两个参数,有返回值,没有返回值,这六种情况都罗列下:

    public class Program {
    	public static void main(String[] args) {
    		If1 if1 = ()->{
    			System.out.println("无参数无返回值");
    		};
    		if1.test();
    
            If2 if2 = (int a)->{
            	System.out.println("单个参数无返回值 a="+a);
            if2.test(3);
    
            If3 if3 = (int a,int b)->{
            	System.out.println("两个参数无返回值 a+b"+(a+b));
            };
            if3.test(1,5);
    
            If4 if4 = ()->{
            	return 4;
            };
            System.out.println("无参数有返回值"+if4.test();
    
            If5 if5 = (int a)->{
            	return a;
            };
            System.out.println("单个参数有返回值"+if5.test(5));
    
            If6 if6 = (int a,int b)->{
            	return a-b;
            };
            System.out.println("多个参数有返回值"+if6.test(7,1));
    	}
    	
     
        interface If1{
        	/**
        	*无参数无返回值
        	*/
        	void test();
        }
    
        interface If2{
        	/**
        	*单个参数无返回值
        	*/
        	void test(int a);
        }
        
        interface If3{
        	/**
        	*两个参数无返回值
        	*/
        	void test(int a,int b);
        }
    
        interface If4{
        	/**
        	*无参数有返回值
        	*/
        	int test();
        }
    
    	interface If5{
    		/**
    		*单个参数有返回值
    		*/
    		int test(int a);
    	}
    
    	interface If6{
    	    /**
    		*多个参数有返回值
    		*/
    		int test(int a,int b);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    Lambda表达式精简语法
    1.参数类型可以省略
    2.假如只有一个参数,()括号可以省略
    3.如果方法体只有一条语句,{}大括号可以省略
    4.如果方法体中唯一的语句是return返回语句,那省略大括号的同时return也要省略

    public class Program2 {
    	public static void main(String[] args) {
    		If1 if1 = ()->System.out.println("无参数无返回值");
    		if1.test();
    
            If2 if2 = a->System.out.println("单个参数无返回值 a="+a);
            if2.test(3);
    
            If3 if3 = (a,b)->System.out.println("两个参数无返回值 a+b"+(a+b));
            if3.test(1,5);
    
            If4 if4 = ()-> 4;
            System.out.println("无参数有返回值"+if4.test();
    
            If5 if5 = a->a;
            System.out.println("单个参数有返回值"+if5.test(5));
    
            If6 if6 = (a,b)->a-b;
            System.out.println("多个参数有返回值"+if6.test(7,1));
    	}
    	
     
        interface If1{
        	/**
        	*无参数无返回值
        	*/
        	void test();
        }
    
        interface If2{
        	/**
        	*单个参数无返回值
        	*/
        	void test(int a);
        }
        
        interface If3{
        	/**
        	*两个参数无返回值
        	*/
        	void test(int a,int b);
        }
    
        interface If4{
        	/**
        	*无参数有返回值
        	*/
        	int test();
        }
    
    	interface If5{
    		/**
    		*单个参数有返回值
    		*/
    		int test(int a);
    	}
    
    	interface If6{
    	    /**
    		*多个参数有返回值
    		*/
    		int test(int a,int b);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    **方法引用** 有时候多个lambda表达式实现函数是一样的话,我们可以封装成通用方法,以便于维护,这时候可以用方法引用实现: 语法是:对象::方法 假如是static方法,可以直接 类名::方法 实例如下:
    public class Program3 {
    	public static void main(String[] args) {
            //If5 if5 = a->a-2;
            //System.out.println(if5.test(3));
    
            //If5 if52 = a->a-2;
            //System.out.println(if5.test(5));
    
    		Program3 program3 = new Program3();
    		If5 if5 = program3::testA;
    		System.out.println(if5.test(3));
    
    		If5 if52 = program3::testA;
    		System.out.println(if52.test(5));
    
    		If5 if53 = Program3::testB;
    		If5 if54 = Program3::testB;
    		System.out.println(if53.test(3));
    		System.out.println(if54.test(3));
    	}
    	
    	public int testA(int a) {
    		return a-2;
    	}
    
    	public static int testB(int a) {
    		return a-2;
    	}
    	
    	interface If5{
    		/**
    		*单个参数有返回值
    		*/
    		int test(int a);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    构造方法引用
    如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用;
    语法:类名::new
    实例:
    先定义一个Dog实体,实现无参和有参构造方法;

    public class Dog {
    	private String name;
    	private int age;
    	
    	public Dog() {
    		System.out.println("无参构造方法");
    	}
    
    	public Dog(String name,int age) {
    		System.out.println("有参构造方法");
    		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 getAge(int age) {
    		this.age = age;
    	}
    
        @Ovrride
        public String toString() {
        	return "Dog(" +
        			"name+'" + name + '\' +
        			", age=" + age +
        			")";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    public class Program4 {
    	public static void main(String[] args) {
    		/*DogService dogService=()->{
    			return new Dog();
    		};
    		System.out.println(dogService.getGog());*/
    
            /*DogService dogService=()->new Dog();
    		System.out.println(dogService.getGog());*/
    
    		DogService dogService=Dog::new;
    		System.out.println(dogService.getGog());
    
    		DogService dogService2=Dog::new;
    		System.out.println(dogService2.getDog("向玉明",24))
    	}
    
    	interface DogService{
    		Dog getDog();
    	}
    
    	interface DogService2{
    		Dog getDog(String name,int age);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    @FunctionallInterface注解
    这个注解是函数式接口注解,所谓的函数式接口,首先的一个接口,然后这个接口里面只能有一个抽象方法
    这种类型的接口也成为SAM接口,即Single Abstract Method interfaces

    特点

    • 接口有且仅有一个抽象方法
    • 允许定义静态方法
    • 允许定义默认方法
    • 允许java.lang.Object中的public方法
    • 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错
    //正确的函数式接口
    @FunctionalInterface
    public interface TestInterface {
    	//抽象方法
    	public void sub();
    
    	//java.lang.Object中的public方法
    	public boolean equals(Object var1);
    
    	//默认方法
    	public default void defaultMethod(){
    	}
    
    	//静态方法
    	public static void staticMethod(){
    	}
    }
    
    //错误的函数式接口(有多个抽象方法)
    @FunctionalInterface
    public interface TetInterface2 {
    	void add();
    	void sub();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    MDM现代设备管理解决方案如何保护企业设备安全,保证员工工作体验?
    libigl 网格等值线
    使用51单片机控制lcd1602字体显示
    您与1秒钟测量两千个尺寸之间仅差一台智能测径仪!
    【sciter】安全应用列表控件总结
    报错记录—feign转对象为linkedHashMap
    Java基础-JVM:垃圾回收算法与垃圾收集器
    Swift中和C语言数据类型转换
    海外代理IP如何找到靠谱的?
    【CSS3】
  • 原文地址:https://blog.csdn.net/weixin_42594143/article/details/126810788