Java8新特性--Lambda表达式

一、简述

Lambda 表达式,也可称为闭包,它

允许把函数作为一个方法的参数 (

数作为参数传递进方法中)

Lambda 简化了匿名内部类的形式,

可以达到同样的效果,匿名内部类在

编译之后会创建一个新的匿名内部类

出来,而 Lambda 是调用

JVM invokedynamic 指令实现的,并

不会产生新类

Lambda表达式返回的是接口对象实例

(2) 基本语法:

(参数列表) → {

        方法体

};

是 Lambda 运算符,英文名是

goes to

二、Lambda 表达式语法

6 种情况:

public class Test {
    public static void main(String[] args) {
        I01 i01 = () -> {
            System.out.println("无返回值、无参数");
        };
        I02 i02 = (int a) -> {
            System.out.println("无返回值,单个参数。a=" + a);
        };
        I03 i03 = (int a, int b) -> {
            System.out.println("无返回值,多个参数。a=" + a + ",b=" + b);
        };
        I04 i04 = () -> {
            System.out.println("有返回值、无参数");
            return 4;
        };
        I05 i05 = (int a) -> {
            System.out.println("有返回值,单个参数。a=" + a);
            return 5;
        };
        I06 i06 = (int a, int b) -> {
            System.out.println("有返回值,多个参数。a=" + a + ",b=" + b);
            return 6;
        };
        i01.method();
        i02.method(5);
        i03.method(5,10);
        System.out.println(i04.method());
        System.out.println(i05.method(5));
        System.out.println(i06.method(5, 10));
    }
}

interface I01 {
    void method();
}

interface I02 {
    void method(int a);
}

interface I03 {
    void method(int a, int b);
}

interface I04 {
    int method();
}

interface I05 {
    int method(int a);
}

interface I06 {
    int method(int a, int b);
}

输出:

无返回值、无参数
无返回值,单个参数。a=5
无返回值,多个参数。a=5,b=10
有返回值、无参数
4
有返回值,单个参数。a=5
5
有返回值,多个参数。a=5,b=10
6

三、函数式接口 (Functional Interface)

Java 8 为了使现有的函数更加友好地

支持 Lambda 表达式,引入了函数式

接口的概念

函数式接口本质上是一个仅有一个抽

象方法的普通接口,所以又叫 SAM 

口 (Single Abstract Method Interface)

函数式接口在实际使用过程中很容易

出错,比如某人在接口定义中又增加

了另一个方法,则该接口不再是函数

式接口,此时将该接口转换为 Lambda

表达式会报错。为了克服函数式接口

的脆弱性,并且能够明确声明接口是

作为函数式接口的意图,Java 8增加

了**@FunctionalInterface**注解来标

注函数式接口。

使用@FunctionalInterface注解标注的

接口必须函数式接口,也就是说该

接口中只能声明一个抽象方法,如果

声明多个抽象方法就会报错。但是默

认方法和静态方法不属于抽象方法,

因此在函数式接口中也可以定义默认

方法静态方法

@FunctionalInterface
interface InterfaceDemo {
    void method(int a);
    static void staticMethod() {
        ...
    }
    default void defaultMethod() {
        ...
    }
}

四、Lambda 表达式精简语法

① 参数类型可以省略

I02 i02 = (int a) -> {System.out.println(...);};

I02 i02 = (a) -> {System.out.println(...);};

② 假如只有一个参数,那么()括号

    可以省略

I02 i02 = (a) -> {System.out.println(...);};

I02 i02 = a -> {System.out.println(...);};

③ 假如方法体只有一条语句,那么语

   句后的;分号和方法体的{}大括号可

   以一起省略

I02 i02 = a -> {System.out.println(...);};

I02 i02 = a -> System.out.println(...);

④ 如果方法体中唯一的语句是 return

   返回语句,那么在省略第3种情况的 

   同时,return也必须一起省略

I05 i05 = a -> {return 1;};

I05 i05 = a -> 1;

五、方法引用(Method Reference)

在Java 8中可以用方法引用来进一

步简化 Lambda 表达式

有时候多个 Lambda 表达式的实现

函数是一样的,我们可以封装成一

个通用方法,再通过方法引用

现接口

1. 方法引用语法

① 如果是实例方法

对象名::实例方法名

② 如果是静态方法

类名::实例方法名

③ 如果是构造方法

类名::new

2. 实例方法引用

public class Test {

    public void eat(int a) {
        System.out.println("吃东西。" + "a=" + a);
    }

    public static void main(String[] args) {
        //Lambda表达式写法:
        Dog dog1 = (a) -> System.out.println("吃东西。" + "a=" + a);
        Cat cat1 = (a) -> System.out.println("吃东西。" + "a=" + a);
        dog1.doSomething(5);
        cat1.doSomething(5);
        //方法引用写法:
        Test test = new Test();
        Dog dog2 = test::eat;
        Cat cat2 = test::eat;
        dog2.doSomething(10);
        cat2.doSomething(10);
    }
}

@FunctionalInterface
interface Dog {
    void doSomething(int a);
}

@FunctionalInterface
interface Cat {
    void doSomething(int a);
}

3. 构造方法引用

如果函数式接口的实现恰好可以通过

调用一个类的构造方法来实现 (比如

说接口方法与这个构造方法的参数个

数、参数类型和返回值都对的上),那

么就可以使用构造方法引用

public class Test {

    public void eat(int a) {
        System.out.println("吃东西。" + "a=" + a);
    }

    public static void main(String[] args) {
		//Lambda表达式写法:
        DogService dogService1 = (name, age) -> new Dog(name, age);
        System.out.println(dogService1.getDog("大狗", 5));
        //方法引用写法:
        DogService dogService2 = Dog::new;
        System.out.println(dogService2.getDog("二狗", 3));
    }
}

@FunctionalInterface
interface DogService {
    Dog getDog(String name, int age);
}

class Dog {

    String name;
    int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

六、内置函数式接口

java.util.function 包下有一系列内

置函数式接口,也是 Java 8 伴随

Lambda 表达式一起推出的

/*
 * Java8 内置的四大核心函数式接口
 * 
 * Consumer<T> : 消费型接口
 * 		void accept(T t);
 * 
 * Supplier<T> : 供给型接口
 * 		T get(); 
 * 
 * Function<T, R> : 函数型接口
 * 		R apply(T t);
 * 
 * Predicate<T> : 断言型接口
 * 		boolean test(T t);
 * 
 */
public class TestLambda3 {
	
	//Predicate<T> 断言型接口:
	@Test
	public void test4(){
		List<String> list = Arrays.asList("Hello", "atguigu", "Lambda", "www", "ok");
		List<String> strList = filterStr(list, (s) -> s.length() > 3);
		
		for (String str : strList) {
			System.out.println(str);
		}
	}
	
	//需求:将满足条件的字符串,放入集合中
	public List<String> filterStr(List<String> list, Predicate<String> pre){
		List<String> strList = new ArrayList<>();
		
		for (String str : list) {
			if(pre.test(str)){
				strList.add(str);
			}
		}
		
		return strList;
	}
	
	//Function<T, R> 函数型接口:
	@Test
	public void test3(){
		String newStr = strHandler("\t\t\t 我大尚硅谷威武   ", (str) -> str.trim());
		System.out.println(newStr);
		
		String subStr = strHandler("我大尚硅谷威武", (str) -> str.substring(2, 5));
		System.out.println(subStr);
	}
	
	//需求:用于处理字符串
	public String strHandler(String str, Function<String, String> fun){
		return fun.apply(str);
	}
	
	//Supplier<T> 供给型接口 :
	@Test
	public void test2(){
		List<Integer> numList = getNumList(10, () -> (int)(Math.random() * 100));
		
		for (Integer num : numList) {
			System.out.println(num);
		}
	}
	
	//需求:产生指定个数的整数,并放入集合中
	public List<Integer> getNumList(int num, Supplier<Integer> sup){
		List<Integer> list = new ArrayList<>();
		
		for (int i = 0; i < num; i++) {
			Integer n = sup.get();
			list.add(n);
		}
		
		return list;
	}
	
	//Consumer<T> 消费型接口 :
	@Test
	public void test1(){
		happy(10000, (m) -> System.out.println("每次消费:" + m + "元"));
	} 
	
	public void happy(double money, Consumer<Double> con){
		con.accept(money);
	}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值