Lambda

Lambda表达式


1.Lambda表达式简介

1.1.什么是Lambda表达式

  Lambda是Java 8添加的一个新特性.说白了,Lambda就是匿名函数

1.2.为什么要使用Lambda?

  使用Lambda表达式可以对接口进行非常简洁的实现

package com.Lambda;

public class Program {
	public static void main(String[] args) {
		
		/**
		 * 2. 使用匿名内部类
		 */
		Comparator comparator2 = new Comparator(){
			@Override
			public int comparator(int a, int b) {
				return a-b;
			}
			
		};
		
		//3. 使用Lambda表达式
		Comparator comparator3 = (a,b) -> a-b;
		
	}
}
/**
 * 1. 接口的实现类,Comparator comparator1 = new MyComparator();
 */
class MyComparator implements Comparator{

	@Override
	public int comparator(int a, int b) {
		return a-b;
	}
}
interface Comparator{
	int comparator(int a,int b);
}
1.3.Lambda对接口的要求

  虽然可以使用Lambda表达式对某些接口进行简单的实现,但是并不是所有的接口都可以用Lambda表达式来实现.要求接口中定义的必须要实现的抽象方法只能是一个

在Java8对接口加了一个新的特性: default ,可以对方法进行默认实现;对Lambda的实现没有影响

@FunctionalInterface
  用来修饰函数式接口的,接口中的抽象方法只有一个

2.Lambda表达式基础语法

首先创建若干个接口

	package interfaces;
	@FunctionalInterface
	public interface LambdaNoneReturn {
		void test();
	}
	
	package interfaces;
	@FunctionalInterface
	public interface LambdaNoneReturnSingleParameter {
		void test(int a);
	}
	
	package interfaces;
	@FunctionalInterface
	public interface LambdaNoneReturnMutipleParameter {
		void test(int a,int b);
	}
	
	package interfaces;
	@FunctionalInterface
	public interface LambdaReturnNoneParameter {
		int test();
	}
	
	package interfaces;
	@FunctionalInterface
	public interface LambdaSingleReturnParameter {
		int test(int a);
	}
	
	package interfaces;
	@FunctionalInterface
	public interface LambdaMutipleReturnParameter {
		int test(int a,int b);
	}

Lambda基础语法
  Lambda是个匿名函数,普通函数要有返回值类型 、方法名、参数列表、方法体;而对于Lambda来说我们关心的是参数列表方法体

( ) : 用来描述参数列表
-> : lmbda运算符号 ,读作goes to
{ } : 用来描述方法体

package lmbdaSyntax;

import interfaces.LambdaNoneReturn;

public class Sytax1 {
	public static void main(String[] args) {
		
		//无参无返回
		LambdaNoneReturn l1 = () -> {System.out.println("hello world");};
		l1.test();
		
		//单参无返回
		LambdaNoneReturnSingleParameter l2 = (int a) -> {System.out.println(a);}; 
		l2.test(100);
		
		//多参无返回
		LambdaNoneReturnMutipleParameter l3 = (int a,int b) -> {System.out.println(a+b);};
		l3.test(10, 15);
		
		//无参有返回
		LambdaReturnNoneParameter l4 = () ->{return "Hello world"; };
		String str = l4.test();
		
		//单参有返回
		LambdaSingleReturnParameter l5 =(int a) ->{
			System.out.println(a);
			return a;
		};
		l5.test(100);

		//多参有返回
		LambdaMutipleReturnParameter l6 = (int a,int b) -> {
			System.out.println(a+b);
			return a+b;
		};
		l6.test(6, 13);
	}	
}

3.Lambda表达式语法精简

  • 参数: 由于在接口的抽象方法中,已经定义了了参数的数量和类型,所以在Lmbda表达式中,参数可以省略类型
    备注 : 如果需要省略类型,则每个参数的类型都要省略
	LambdaNoneReturnMutipleParameter lambda1 = (a, b) -> {
		System.out.println(a+b);
	};
  • 参数小括号: 如果参数列表中,参数的数量只有一个,此时小括号可以省略
	LambdaNoneReturnSingleParameter lambda2 = a -> {
		System.out.println(a);
	};
  • 方法大括号: 方法体中只有条语句的情况下大括号可以省略
LambdaNoneReturnMutipleParameter lambda3 = (a,b) -> System.out.println("hello world");
  • 返回值: 如果方法体中唯一的一条语句是一个返回值,则在省略掉大括号的同时,也必须省略掉return
LambdaReturnNoneParameter lambda4 = () -> "hello world";
LambdaMutipleReturnParameter lambda5 =(a,b) -> a+b;

4.Lambda表达式语法进阶

  方法引用: 可以快速的将一个Lambda表达式的实现,指向一个已经实现的方法

语法 :方法的隶属者(类,或者对象)::方法名

注意:

  1. 参数数量和类型一定要和接口中定义的方法一致
  2. 返回值的类型一定要和接口中定义的方法一致
	 package lmbdaSyntax;

import interfaces.LambdaMutipleReturnParameter;

public class Sytax3 {
	public static void main(String[] args) {	
		//这样会造成冗余,我们可以对(a,b) -> a+b进行封装
		LambdaMutipleReturnParameter Lambda1 = (a,b) -> a+b;
		LambdaMutipleReturnParameter Lambda2 = (a,b) -> a+b;
		
		//封装后变成这样
		LambdaMutipleReturnParameter Lambda3 = (a,b) -> change( a, b);
		
		/**
		 * 等价于
		 * 方法引用 : 引用了change方法的实现
		 */
		LambdaMutipleReturnParameter Lambda4 =Sytax3::change;
		int test = Lambda4.test(1, 2);
	}
	
	private static int change(int a,int b){
		return a+b;
	}
}	

  构造方法的引用:

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("带参");
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

package lmbdaSyntax;

import Data.Person;

public class Sytax4 {
	public static void main(String[] args) {
		PersonCreater p1 = ()-> {
			return new Person();
		};
	
		PersonCreater p2 = ()-> new Person();
		
		//构造方法的引用
		PersonCreater p3 = Person :: new; 
		Person person = p3.getPerson();
		
		/**
		 * 具体引用有参还是无参根据接口中的参数而定
		 */
		PersonCreater2 p4 = Person :: new; 
		Person person2 = p4.getPerson("小明",10);
	}
}

interface PersonCreater{
	Person getPerson();
}

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

5.Lambda表达式案例

package exercise;

import java.util.ArrayList;

import Data.Person;

public class Exercise1 {
	//集合排序:
	//ArrayList<>
	
	public static void main(String[] args){
		// 需求:已知在一个ArrayList中有若个Person对象,将这些Person对象按照年龄进行降序排序
		ArrayList<Person> list = new ArrayList<>();
		
		list.add(new Person("小明",10));
		list.add(new Person("小红",11));
		list.add(new Person("小张",12));
		list.add(new Person("小王",12));
		list.add(new Person("小李",14));
		list.add(new Person("小刚",15));
		
		list.sort((o1,o2) ->{
			return o2.age-o1.age;
			
		});
		list.sort((o1,o2) -> o2.age-o1.age);
		System.out.println(list);
	}
}

package exercise;

import java.util.TreeSet;
import Data.Person;

public class Exercise2 {
	//set排序:
	//TreeSet<>
	
	public static void main(String[] args){
		/*TreeSet<Person> set = new TreeSet<>();
		
		set.add(new Person("小明",10));
		set.add(new Person("小红",11));
		set.add(new Person("小张",12));
		set.add(new Person("小王",13));
		set.add(new Person("小李",14));
		set.add(new Person("小刚",15));*/
		//java.lang.ClassCastException: Data.Person cannot be cast to java.lang.Comparable
		//System.out.println(set);
	
		
		
		/**
		 * 使用Lambda表达式来实现Comparable接口,并实例化一个TreeSet对象
		 */
		TreeSet<Person> set2 = new TreeSet<>((o1,o2) -> {
			if(o1.age>=o2.age){
				return -1;
			}else{
				return 1;
			}
			
		});
		set2.add(new Person("小明",10));
		set2.add(new Person("小红",11));
		set2.add(new Person("小张",12));
		set2.add(new Person("小王",12));
		set2.add(new Person("小李",14));
		set2.add(new Person("小刚",15));
		System.out.println(set2);
		
		
	}
}

package exercise;

import java.util.ArrayList;
import java.util.Collections;

public class Exercise3 {
	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<>();
		
		Collections.addAll(list, 1,2,3,4,5,6,7,8,9,0);
		
		// 将集合中的每个元素都带入到方法accept中
		//list.forEach(System.out::println);
	
		//遍历集合中所有的偶数
		list.forEach(ele -> {
			if(ele%2==0){
				System.out.println(ele);
			}
		});
		list.sort((o1,o2) -> o1-o2);
		System.out.println(list);
	} 
}

package exercise;

import java.util.ArrayList;
import java.util.Iterator;

import Data.Person;

public class Exercise4 {
	//删除元素
	public static void main(String[] args){
		ArrayList<Person> list = new ArrayList<>();
		
		list.add(new Person("小明",10));
		list.add(new Person("小红",11));
		list.add(new Person("小张",12));
		list.add(new Person("小王",13));
		list.add(new Person("小李",14));
		list.add(new Person("小刚",15));
		
		//使用迭代器
		Iterator<Person> listIterator = list.iterator();
		while (listIterator.hasNext()) {
			Person ele =  listIterator.next();
			if(ele.age>10){
				listIterator.remove();
			}
		}
		
		//使用Lambda
		list.removeIf(ele -> ele.age>10);
		System.out.println(list);
	}

}
package exercise;

public class Exercise5 {
	public static void main(String[] args) {
		new Thread(() -> {
			System.out.println("创建线程");
		}).start();
	}

	
}

6.系统内置函数式接口

常用的函数式接口

	@FunctionalInterface
	public interface Predicate<T> {
		boolean test(T t); //参数T 返回值boolean
	}
	@FunctionalInterface
	public interface Consumer<T> {
		void accept(T t); //参数T 返回值void
	}
	@FunctionalInterface
	public interface Function<T, R> {
		R apply(T t); //参数T 返回值R
	}
	@FunctionalInterface
	public interface Supplier<T> {
		T get(); //无参 返回值T
	}


了解

	@FunctionalInterface
	public interface UnaryOperator<T> extends Function<T, T> {	
	  static <T> UnaryOperator<T> identity() {
        	return t -> t; //参数T 返回值T
    	}
	}
	@FunctionalInterface
	public interface BiFunction<T, U, R> {
		R apply(T t, U u);
	}
	@FunctionalInterface
	public interface BinaryOperator<T> extends BiFunction<T,T,T> {   // 参数T, T 返回值T
		public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
	        Objects.requireNonNull(comparator);
	        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
	    }
	    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
	        Objects.requireNonNull(comparator);
	        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
	    }

7.闭包

	package closure;
	
	import java.util.function.Supplier;
	
	public class ClosureDemo {
		public static void main(String[] args) {
			int n = getNumber().get();
			System.out.println(n); //打印了10
			/*
			 * 思考:为什么打印10,方法结束[getNumber()]局部变量应该被销毁
			 * num在方法结束时,不会被销毁
			 */
		}
		private static Supplier<Integer> getNumber(){
			
			int num =10;
			//用方法把变量包裹起来就叫闭包;闭包会提升包裹变量的声明周期;我们可以闭包来获得某一方法的局部变量
			return () -> {
				return num;
			};
		}
	}
	package closure;
	
	import java.util.function.Consumer;
	
	public class ClosureDemo2 {
		public static void main(String[] args) {
			int a =10;
			Consumer<Integer> c =ele -> {
	//Local variable a defined in an enclosing scope must be final or effectively final
				System.out.println(a++);
			};
			c.accept(a);
			/**
			 * 如果你在闭包中使用了局部变量,那么默认用final修饰,使其成为常量(无法修改)
			 * final int a =10;
			 */
		}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值