lambda表达式

参考网址!!!!!!

1.背景介绍

  1. lambda是java8的新特性---->匿名函数
  2. lambda用于接口的简洁实现(接口的实现有三种方式)
  3. lambda要求接口中只有一个抽象方法(java8引入的default修饰除外)
  4. 函数式接口:接口中只有一个抽象方法(可使用@FunctionalInterface对接口进行编译检查)

1.1 接口的三种实现方式

package com.zhanglei.interfaceImplementsMethods;

public class Test1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//1.实现类实现接口
		Comparator c1=new MyComparator();
		int r1=c1.comparator(1,2);
		System.out.println("first:"+r1);
		//2.匿名内部类实现接口
		Comparator c2=new Comparator() {
			@Override
			public int comparator(int a,int b) {
				return a-b;
			}
			
		};
		int r2=c2.comparator(1, 3);
		System.out.println("second:"+r2);
		//3.lambda表达式实现接口
		Comparator c3=(a,b)->a-b;
		int r3=c3.comparator(1, 4);
		System.out.println("third:"+r3);
		

	}

}

@FunctionalInterface
interface Comparator{
	int comparator(int a,int b);
}

class MyComparator implements Comparator{
	public int comparator(int a,int b) {
		return a-b;
	}
}

输出:

first:-1
second:-2
third:-3

2. lambda实现接口

2.1 准备多个接口

在这里插入图片描述
示例:

package interfaces;

public interface LambdaNoneReturnMultiParam {
	void test(int a, int b);
}

package interfaces;

public interface LambdaSingleReturnNoParam {
	int test();
}

2.2 传统的lambda实现接口

package syntax;

import interfaces.LambdaNoneReturnMultiParam;
import interfaces.LambdaNoneReturnNoParam;
import interfaces.LambdaNoneReturnSingleParam;
import interfaces.LambdaSingleReturnMultiParam;
import interfaces.LambdaSingleReturnNoParam;
import interfaces.LambdaSingleReturnSingleParam;

public class Syntax1 {
	public static void main(String[] args) {
	//1.lambda基础语法
		
	    //lambda为匿名函数
	    //函数组成:返回值类型,方法名,参数列表,方法体
	    //匿名函数组成:参数列表,方法体
	  
	    // ():参数列表
	    // {}:方法体  
	    // ->:lambda运算符,读作goes to
		
	//2.lambda测试
		//2.1 无参无返回
		LambdaNoneReturnNoParam l1=()->{
			System.out.println("我是无参无返回");
		};
		l1.test();
	    //2.2 单参无返回
		LambdaNoneReturnSingleParam l2=(int a)->{
			System.out.println("我是单参无返回"+a);
		};
		l2.test(11);
		//2.3 多参无返回
		LambdaNoneReturnMultiParam l3=(int a,int b)->{
			System.out.println("我是多参无返回"+a+" "+b);
		};
		l3.test(11, 22);
		//2.4 无参有返回
		LambdaSingleReturnNoParam l4=()->{
			return 111;
		};
		int r1=l4.test();
		System.out.println("我是无参有返回"+r1);
		//2.5 单参有返回
		LambdaSingleReturnSingleParam l5=(int a)->{
			return a;
		};
		int r2=l5.test(222);
		System.out.println("我是单参有返回"+r2);
		//2.6 多参有返回
		LambdaSingleReturnMultiParam l6=(int a,int b)->{
			return a+b;
		};
		int r3=l6.test(111,222);
		System.out.println("我是多参有返回"+r3);
		
	}
}

输出:

我是无参无返回
我是单参无返回11
我是多参无返回11 22
我是无参有返回111
我是单参有返回222
我是多参有返回333
  1. 注意看注释部分
  2. 传统的lambda写法还是很多代码

2.3 精简的lambda写法

package syntax;

import interfaces.LambdaNoneReturnMultiParam;
import interfaces.LambdaNoneReturnNoParam;
import interfaces.LambdaNoneReturnSingleParam;
import interfaces.LambdaSingleReturnMultiParam;

public class Syntax2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
	//语法精简
		//1.参数类型
		//由于接口中定义了参数的类型和数量,所以lambda中可以省略其类型(要省略就全部省略不能部分省略)
		LambdaNoneReturnMultiParam l1=(a,b)->{
			System.out.println("参数类型省略");
		};
		l1.test(1, 1);
		
		//2.参数小括号
		//如果参数只有一个,则小括号可以省略
		LambdaNoneReturnSingleParam l2=a->{
			System.out.println("参数小括号省略");
		};
		l2.test(1);
		
		//3.方法体大括号
		// 如果方法体中只有一条语句,则大括号可以省略,分为有return和无return
		// 无return,直接省略大括号
		LambdaNoneReturnNoParam l3=()->System.out.println("方法大括号省略");
		l3.test();
		// 有return,直接省略return和大括号
		LambdaSingleReturnMultiParam l4=(a,b)->a-b;
		int r1=l4.test(1, 2);
		System.out.println("方法大括号省略之return"+r1);
		
	}

}

输出:

参数类型省略
参数小括号省略
方法大括号省略
方法大括号省略之return-1

2.4 进阶的方法引用

package syntax;

import interfaces.LambdaSingleReturnSingleParam;

public class Syntax3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//方法引用:
		//将lambda表达式的实现指向一个已经实现的方法(当方法需要多次调用和修改时)
		//格式:方法的隶属者::方法名
		
		LambdaSingleReturnSingleParam l0=a-> a*2;
		LambdaSingleReturnSingleParam l1=a-> change(a);
		System.out.println(l1.test(1));
		// 静态方法对应 类名::方法名
		LambdaSingleReturnSingleParam l2=Syntax3::change;
		System.out.println(l2.test(3));
		Syntax3 s3=new Syntax3();
		// 实例方法对应 对象::方法名
		LambdaSingleReturnSingleParam l3=s3::change3;
		System.out.println(l3.test(5));
	}
	
	public static int change(int a) {
		return a*2;
	}
	
	public int change3(int a) {
		return a*3;
	}

}

输出:

2
6
15

2.5 进阶的构造方法引用

package data;

public class Person {
	private String name;
	private int age;
	public Person() {
		System.out.println("无参构造被调用!");
	}
	public Person(String name,int age) {
		this.name=name;
		this.age=age;
		System.out.println("有参构造被调用!");
	}
}
package syntax;

import data.Person;

public class Syntax4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		PersonCreator1 pc1=()->{
			return new Person();
		};
		PersonCreator1 pc2=()->new Person();
		
		//构造方法的引用
		PersonCreator1 pc3=Person::new;
		Person a=pc3.getPerson();
		
		PersonCreator2 pc4=Person::new;
		Person b=pc4.getPerson("zhanglei", 25);
		
	}

}


//函数式接口,保证只有一个抽象方法!!!
interface PersonCreator1{
	Person getPerson();
//	Person getPerson(String name,int age);
}

interface PersonCreator2{
//	Person getPerson();
	Person getPerson(String name,int age);
}

输出:

无参构造被调用!
有参构造被调用!

3.lambda实战

3.1 集合排序

package data;

public class Person {
	public String name;
	public int age;
	public Person() {
		System.out.println("无参构造被调用!");
	}
	public Person(String name,int age) {
		this.name=name;
		this.age=age;
		System.out.println("有参构造被调用!");
	}
	public String toString(String name,int age) {
		return "Person的name为:"+name+",年龄为:"+age;
	}
	public String toString() {
		return "Person的name为:"+name+",年龄为:"+age;
	}
}
  1. toString无参才是重写,有参是普通方法
package Exercise;

import java.util.ArrayList;

import data.Person;

public class Exercise1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ArrayList<Person> a1=new ArrayList<>();
		a1.add(new Person("zhangsan",21));
		a1.add(new Person("lisi",22));
		a1.add(new Person("wangwu",23));
		a1.add(new Person("zhaoliu",19));
		a1.add(new Person("zhangniu",24));
		a1.add(new Person("zhangwei",25));
		//排序1
		a1.sort((o1,o2)->o1.age-o2.age);
		System.out.println(a1);
		//排序1
		a1.sort((o1,o2)->o2.age-o1.age);
		System.out.println(a1);
	}

}

输出:

有参构造被调用!
有参构造被调用!
有参构造被调用!
有参构造被调用!
有参构造被调用!
有参构造被调用!
[Person的name为:zhaoliu,年龄为:19, Person的name为:zhangsan,年龄为:21, Person的name为:lisi,年龄为:22, Person的name为:wangwu,年龄为:23, Person的name为:zhangniu,年龄为:24, Person的name为:zhangwei,年龄为:25]
[Person的name为:zhangwei,年龄为:25, Person的name为:zhangniu,年龄为:24, Person的name为:wangwu,年龄为:23, Person的name为:lisi,年龄为:22, Person的name为:zhangsan,年龄为:21, Person的name为:zhaoliu,年龄为:19]

  1. public void sort(Comparator<? super E> c) 参数为Comparator接口
  2. 该接口是函数式接口(其中的equals方法不是抽象方法!)
  3. 如此就可以使用lambda表达式
  4. lambda表达式来实现int compare(T o1,T o2)
  5. 当其返回值小于0,等于0,大于0分别对应o1小于o2,o1等于o2,o1大于大于o2
  6. 因此可以利用返回值来进行升序和降序的选择
  7. 思考为什么o1.age-o2.age和o2.age-o1.age可以对应升序和降序
  8. 考察源码和算法能力了

3.2 集合遍历(for each)

package exercise;
import java.util.ArrayList;
import java.util.Collections;
public class Exercise2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ArrayList<Integer> a1=new ArrayList<>();
		Collections.addAll(a1,1,2,3,4,5,6,7,8,9,10);
		
		//方法引用实现Consumer函数式接口中的accept方法
		a1.forEach(System.out::println);
		
		System.out.println("******");
		//输出集合中所有的偶数
		a1.forEach(ele->{
			if(ele%2==0) {
				System.out.println(ele);
			}
		});
	}

}

输出:

1
2
3
4
5
6
7
8
9
10
******
2
4
6
8
10

3.3 线程实例化

package exercise;

public class Exercise3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread th=new Thread(()->{
			for(int i=0;i<10;i++) {
				System.out.println(i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		th.start();
	}

}

输出:

0
1
2
3
4
5
6
7
8
9

解释:

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}
  1. Runnable接口是函数式接口,所以可以用lambda表达式实例化线程对象
  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值