zoukankan      html  css  js  c++  java
  • JavaSE-29 Java8的Lambda表达式

    概念说明

    • Lambda表达式是Java8提供的新特性,支持将代码块作为方法的参数。
    • Lambda表达式支持使用简洁的代码创建只有一个方法的接口(函数式接口)。
    • 只包含一个方法的接口也称为函数式接口。

     Lambda表达式示例

    在命令模式的例子中(地址:http://www.cnblogs.com/rask/p/8309876.html),可以直接向业务处理类方法传入实际代码,有两种实现方式:局部匿名内部类和Lambda表达式。

    public class Test {
    	public static void main(String[] args) {
    		DataProcess dp = new DataProcess();
    		int[] data = { 1, 2, -10, 9, 18 };
    
    		// 使用局部内部类
    		dp.service(data, new ICommand() {
    			@Override
    			public void process(int[] data) {
    				System.out.print("数组data中的元素有:");
    				for (int item : data) {
    					System.out.print(item + "  ");
    				}
    			}
    		});
    
    		// 使用lambda表达式
    		dp.service(data, target -> {
    			int sum = 0;
    			for (int i = 0; i < target.length; i++) {
    				sum += data[i];
    			}
    			System.out.println("数组所有元素之和为:" + sum);
    		});
    	}
    }
    

     Lambda表达式的主要作用:用于替换匿名内部类繁琐的语法。

     Lambda表达式语法格式

    (参数类型 参数1,参数类型,参数2)->{代码块}
    
    1. 形参列表:允许省略形参参数类型。如果只有一个参数,圆括号也可以省略。
    2. “->” :使用英文的中画线和大于号表示。
    3. 代码块:如果代码块只有一条语句,可以省略"{}"。如果代码块只有一条return语句,return关键字也可以省略。

    示例代码:

    package com.etc.qs;
    
    /**函数式接口*/
    @FunctionalInterface
    interface OneAble {
    	void method();
    }
    
    /**函数式接口*/
    @FunctionalInterface
    interface TwoAble {
    	void method(String str);
    }
    
    /**函数式接口*/
    @FunctionalInterface
    interface ThreeAble {
    	int method(int a, int b);
    }
    
    public class QSDemo {
    
    	public void OneAbleImpl(OneAble oneAble) {
    		System.out.println(oneAble.toString());
    		oneAble.method();
    	}
    
    	public void TwoAbleImpl(TwoAble twoAble) {
    		System.out.println(twoAble.toString());
    		twoAble.method("Hello Lamda!");
    	}
    
    	public void ThreeAbleImpl(ThreeAble threeAble) {
    		System.out.println("10和15的和为:" + threeAble.method(10, 15));
    	}
    
    	public static void main(String[] args) {
    		QSDemo q = new QSDemo();
    		// Lambda表达式代码块只有一条语句,可以省略"{}"
    		q.OneAbleImpl(() -> System.out.println("新年好!"));
    
    		// Lambda表达式的形参列表只有一个形参,可以省略"()"
    		q.TwoAbleImpl(str -> {
    			System.out.println(str);
    			System.out.println("执行了一个参数的方法!");
    		});
    
    		// Lambda表达式代码块只有一条语句,可以省略"{}",如果该条语句为带返回值,同时可以省略return关键字
    		q.ThreeAbleImpl((a, b) -> a + b);
    
    	}
    }
    

      

    函数式接口

    Lambda表达式的类型,也称为“目标类型”。Lambda表达式的目标类型必须是“函数式”接口(functional interface)。

    函数式接口:只有一个抽象方法的接口。这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。

    Java8提供了函数式接口注解:

    @FunctionalInterface
    

      该注解用于编译时检查接口是否满足函数式接口规范。

    总而言之,Lambda表达式使用限制归纳为以下两点:

    •  Lambda表达式目标类型必须是函数式接口。
    • Lambda只能为函数式接口创建对象。

    Lambda表达式方法引用和构造器引用

    如果Lambda表达式代码块只有一条语句,可以在代码中使用方法引用和构造器引用,使用”::”进行引用。

    引用方式汇总:

    种类 引用示例 说明 对应Lambda表达式
    引用类方法 类名::类方法 函数式接口中被实现方法的全部参数传给该类方法作为参数 (a,b,...)->类名.类方法(a,b,...)
    引用特定对象的实例方法 特定对象::实例方法  函数式接口中被实现方法的全部参数传给该方法作为参数 (a,b,...)->特定对象.实例方法(a,b,...)
    引用某类对象的实例方法 类名::实例方法  函数式接口中被实现方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数  (a,b,...)->a.实例方法(b,...)
    引用构造器 类名::new  函数式接口中被实现方法的全部参数传给该构造器作为参数  (a,b,...)->new 类名(a,b,...) 

    表格数据来源:《疯狂java讲义》

    引用类方法示例代码:

    /**
     * 函数式接口
     * 用于把字符串转换为整数
     *
     */
    @FunctionalInterface
    interface Converter{
    	Integer convert(String from);
    }
    
    
    public class MethodRef {
    	public static void main(String[] args) {
    		//Converter converter=(String from)->{return Integer.valueOf(from);};
    		Converter converter=Integer::valueOf;//引用类方法valueOf
    		Integer val=converter.convert("8899");
    		System.out.println(val);
    	}
    }
    

      

    引用特定对象的实例方法示例代码:

    /**
     * 函数式接口1
     * 判断字符串中是否包含指定字符
     *
     */
    @FunctionalInterface
    interface Converter1{
    	int convert(String from);
    }
    
    
    public class MethodRef {
    	public static void main(String[] args) {
    		Converter1 converter1="etc.com"::indexOf;//indexOf为String类的实例方法
    		int result=converter1.convert("c");
    		System.out.println(result);
    	}
    }
    

      

    引用某类对象的实例方法示例代码:

    /**
     * 函数式接口2
     * 字符串截取
     *
     */
    @FunctionalInterface
    interface Converter2{
    	String convert(String from,int a,int b);
    }
    
    
    public class MethodRef {
    	public static void main(String[] args) {
    		Converter2 converter2=String::substring;//引用String类的实例方法
    		String result=converter2.convert("etc.com",2,4);
    		System.out.println(result);
    	}
    }
    

      

    引用构造器示例代码:

    /**打开一个Frame窗体*/
    @FunctionalInterface
    interface MyFrame {
    	JFrame windows(String title);
    }
    
    
    public class MethodRef {
    	public static void main(String[] args) {
    		MyFrame mf=JFrame::new;//引用JFrame类的构造器
    		JFrame jf=mf.windows("我的窗体");
    		jf.setVisible(true);
    		jf.setSize(400, 400);
    	}
    }
    

      



    本博客文章未经许可,禁止转载和商业用途!

    如有疑问,请联系: 2083967667@qq.com


  • 相关阅读:
    hibernate基础18:HQL
    hibernate基础17:cascade 级联 与 Inverse 反转
    hibernate基础16:有序集合映射
    hibernate基础15:组合主键3
    hibernate基础15:组合主键2
    hibernate基础15:组合主键1
    hibernate基础14:OpenSessionInView(抽取web访问时对数据库开关事务)
    hibernate基础13:关联映射之组件映射
    hibernate基础12:关联映射之基于主键的双项多对多
    Jmeter CSV数据文件设置使用之一
  • 原文地址:https://www.cnblogs.com/rask/p/8310035.html
Copyright © 2011-2022 走看看