一、java8新特性之lambad表达式

目录

第一节:java8新特性简介

一、java8新特性的好处

1、速度更快

2、代码更少

3、强大的streamAPI

4、便于并行

5、最大化的减少空指针异常optional

第二节:lambad表达式

一、lambad表达式的概念

二、为什么使用lambad表达式

1、回顾匿名内部类早期的使用方式、并对比lambad的实现方式

2、结合一个小需求,将传统实现对比lambad表达式实现

3、使用策略设计模式,对上述代码进行优化

4、使用匿名内部类的方式,对上述代码进行优化

5、使用lambad表达式,对上述代码进行优化

6、使用stream,对上述代码进行优化

三、lambad表达式基础语法

1、lambad基础语法概述

四、lambad语法的几种格式

1、无参无返回值

2、有一个参数,并且无返回值

3、如接口中的抽象方法只有一个参数,那么lambad中的参数列表里的小括号可以不写

4、一个以上参数,有返回值,并且lambad体中包含多条语句

5、若lambad中只有一条语句,那么return和大括号都可以省略

6、参数推导

五、lambad表达式与接口关系

1、函数式接口的支持

六、lambad表达式小练习

1、调用collections.sort()方法,通过定制排序比较两个employee(先按年龄比,年龄相同按姓名比),使用lambad作为参数传递;

2、自定义练习题1


Java8的新特性中,有两个特别出彩的地方,一个是lambad表达式,这是一种新的语法。另外,使用lambad结合(也可以不结合)streamAPI,可以使我们操作数据的时候,就像使用sql操作数据一样便捷!甚至,比使用sql语句还要简单!

第一节:java8新特性简介

一、java8新特性的好处

1、速度更快

Java8对底层的数据结构和垃圾回收机制的底层都做了一定的优化,所以他的运行效率要比java8之前更快!

举个例子:

在java8之前,map集合底层使用的是链表+数组去实现的。

Java8之后将其优化为链表+数组+红黑树结构。这种做法可以避免在极端的碰撞情况下导致的效率低下,当某一个链表长度大于8,并且总容量大于64的时候,链表将会转换为红黑树结构,这种结构,除了添加的时候慢一点,其他的操作效率都很高!

另外,在concurrentHashMap中,将之前的分段锁,使用CAS无锁算法进行了替换,CAS无锁的效率大家都知道要比分段锁高很多!

再比如,java8对底层的内存结构也做了一定的调整。他将原来的永久区替换成了元空间,即metaSpace。他使用的是物理内存,而不是分配的内存,这个好处是非常棒的,你物理空间多大,我元空间就可以是多大,他争夺占用的是机器的底层物理资源!

如此一来,垃圾回收机制运行的次数便减少了,也就相应的提高了一定的效率!这里要提出一点,就是这种方式下OOM的发生概率便也随之的大大降低了!

2、代码更少

新增的语法lambad表达式使代码更加的简洁!大大的提高了代码的可读性!

3、强大的streamAPI

这个地方是比较出彩的一个点,他大大的简化了java对数据的操作,使得java在操作数据的时候,可以像sql一样简洁!

4、便于并行

Java8对于并行运行做了一定的优化和支持!

5、最大化的减少空指针异常optional

Java8中提供了一个容器类optional,该类中提供了一系列对空指针的操作,大大的简少了空指针的异常!

 

第二节:lambad表达式

一、lambad表达式的概念

Lambad是一个匿名函数,我们可以把lambad表达式理解为一段可以传递的代码(将代码像数据一样传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使java语言表达能力得到了提升!

二、为什么使用lambad表达式

我们在这里使用实例演示来说明,为什么要使用lambad表达式!

1、回顾匿名内部类早期的使用方式、并对比lambad的实现方式

其实从上述对比的案例中,可以看出来,lambad已经大大的简化了代码的数量,如果这个还无法打动你,那么我们接着看下面的对比案例;

package 为什么要使用lambad表达式;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * 演示为什么要引入lambad表达式1
 * @author yangbao
 */
public class LambadImport1 {
	
	/**
	 * 最早期的匿名内部类使用
	 */
	public void EarlyUseOfAnonymousInnerClasses() {
		
		//创建一个用于比较数值大小的匿名内部类
		Comparator<Integer> com = new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return Integer.compare(o1, o2);
			}
		};
		
		//将匿名内部类作为参数进行传递
		TreeSet<Integer> ts = new TreeSet<Integer>(com);
		
		/**
		 * 分析:上述代码,我们其实核心的,最有用的代码,
		 * 		其实就是匿名内部类中的:return Integer.compare(o1, o2);这一句
		 * 		而其他的一些代码,全部都是为这句代码提供支持的,也就是说,真正
		 *       干活的代码,就那么一句,然后你还要弄些有的没有乱七八糟的代码。
		 *       那么这个时候,lambad就诞生了,他的诞生,就是为了解决掉这些
		 *       有的没有乱七八糟的代码!
		 */
	}
	
	
	/**
	 * 使用lambad表达式实现匿名内部类
	 */
	public void UsingLambadExpressionsToImplementAnonymousInnerClasses() {
		Comparator<Integer> com = (x,y)-> Integer.compare(x,y);
		//将lambad作为参数进行传递
		TreeSet<Integer> ts = new TreeSet<Integer>(com);
	}
	
}

2、结合一个小需求,将传统实现对比lambad表达式实现

我们给出一个小需求:获取当前公司中员工年龄大于35岁的员工信息!

这样的需求在正常工作中是非常常见的,下面我们分别用几种方式对其进行实现,来一一与lambad表达式的实现对比:

1)、最传统的实现方式

package 为什么要使用lambad表达式;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import 为什么要使用lambad表达式.entity.Employee;

/**
 * 演示为什么要引入lambad表达式2
 * 如果演示案例1还不足以说明lambad的好处,
 * 那么我们使用案例演示2来尝试说明lambad的好处!
 * 
 * 在这里我们提出一个明确的需求:
 * 获取当前公司中员工年龄大于35岁的员工信息!
 * 
 * @author yangbao
 */
public class LambadImport2 {
	
	//创建数据
	private static List<Employee> employees = Arrays.asList(
			new Employee("张三",18,9999.99),
			new Employee("李四",38,5555.55),
			new Employee("王五",50,6666.66),
			new Employee("赵六",16,3333.33),
			new Employee("田七", 8,7777.77)
	);

	/**
	 * 获取当前公司中员工年龄大于35岁的员工信息!
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployees(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getAge()>=35) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	public static void main(String[] args) {
		List<Employee> filterEmployees = filterEmployees(employees);
		for(Employee e:filterEmployees) {
			System.out.println(e);
		}
	}
}

运行效果:

Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]

2)、新增需求

好了,当我们将上面的第一个需求实现之后,又来了一个新的需求,这是很常见的吧:

获取当前公司中员工工资大于5000的员工信息。

那这个时候,就意味着我们还得写一个方法,于是,这个类就变成了如下的样子:

package 为什么要使用lambad表达式;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import 为什么要使用lambad表达式.entity.Employee;

/**
 * 演示为什么要引入lambad表达式2
 * 如果演示案例1还不足以说明lambad的好处,
 * 那么我们使用案例演示2来尝试说明lambad的好处!
 * 
 * 在这里我们提出一个明确的需求:
 * 获取当前公司中员工年龄大于35岁的员工信息!
 * 
 * @author yangbao
 */
public class LambadImport2 {
	
	//创建数据
	private static List<Employee> employees = Arrays.asList(
			new Employee("张三",18,9999.99),
			new Employee("李四",38,5555.55),
			new Employee("王五",50,6666.66),
			new Employee("赵六",16,3333.33),
			new Employee("田七", 8,7777.77)
	);
	

	/**
	 * 获取当前公司中员工年龄大于35岁的员工信息!
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployees(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getAge()>=35) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 获取当前公司中员工工资大于5000的员工信息
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployeesSalary(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getSalary()>=5000) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	public static void main(String[] args) {
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployees = filterEmployees(employees);
		for(Employee e:filterEmployees) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeesSalary = filterEmployeesSalary(employees);
		for(Employee e:filterEmployeesSalary) {
			System.out.println(e);
		}
		
	}
}

运行效果:

获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]

实现出来的运行结果是没有问题的,但是这个代码中存在很多的冗余代码,filterEmployees和filterEmployeesSalary两个方法,其实唯一一点不同的地方就是比较的字段不一样!

其余的代码都一样,那么这个时候我们就不得不考虑对其进行抽取封装了!

我们目前来说,对代码最好的优化方式就是使用相应的设计模式,那么我们就使用设计模式来对其进行一个优化:

3、使用策略设计模式,对上述代码进行优化

1)、创建策略接口

package 为什么要使用lambad表达式.inter;

public interface MyPredicate<T> {

	/**
	 * 比较函数
	 * @param t
	 * @return
	 */
	public boolean compare(T t);
		
}

2)、创建实现类

package 为什么要使用lambad表达式.inter.impl;

import 为什么要使用lambad表达式.entity.Employee;
import 为什么要使用lambad表达式.inter.MyPredicate;

public class FilterEmployeeByAge implements MyPredicate<Employee> {

	/**
	 * 实现比较函数
	 */
	@Override
	public boolean compare(Employee t) {
		return t.getAge()>=35;
	}

}
package 为什么要使用lambad表达式.inter.impl;

import 为什么要使用lambad表达式.entity.Employee;
import 为什么要使用lambad表达式.inter.MyPredicate;

public class FilterEmployeeBySalary implements MyPredicate<Employee>  {

	/**
	 * 实现比较函数
	 */
	@Override
	public boolean compare(Employee t) {
		return t.getSalary()>=5000;
	}
	
}

3)、根据不同的策略选择不同的策略接口实现类作为参数

package 为什么要使用lambad表达式;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import 为什么要使用lambad表达式.entity.Employee;
import 为什么要使用lambad表达式.inter.MyPredicate;
import 为什么要使用lambad表达式.inter.impl.FilterEmployeeByAge;
import 为什么要使用lambad表达式.inter.impl.FilterEmployeeBySalary;

/**
 * 演示为什么要引入lambad表达式2
 * 如果演示案例1还不足以说明lambad的好处,
 * 那么我们使用案例演示2来尝试说明lambad的好处!
 * 
 * 在这里我们提出一个明确的需求:
 * 获取当前公司中员工年龄大于35岁的员工信息!
 * 
 * @author yangbao
 */
public class LambadImport2 {
	
	//创建数据
	private static List<Employee> employees = Arrays.asList(
			new Employee("张三",18,9999.99),
			new Employee("李四",38,5555.55),
			new Employee("王五",50,6666.66),
			new Employee("赵六",16,3333.33),
			new Employee("田七", 8,7777.77)
	);
	

	/**
	 * 获取当前公司中员工年龄大于35岁的员工信息!
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployees(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getAge()>=35) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 获取当前公司中员工工资大于5000的员工信息
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployeesSalary(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getSalary()>=5000) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 优化方式1
	 * @param employeesList
	 * @param mp
	 * @return
	 */
	public static List<Employee> filterEmployee(List<Employee> employeesList,MyPredicate<Employee> mp){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee e:employeesList) {
			if(mp.compare(e)) {
				emps.add(e);
			}
		}
		return emps;
	}
	
	
	public static void main(String[] args) {
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployees = filterEmployees(employees);
		for(Employee e:filterEmployees) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeesSalary = filterEmployeesSalary(employees);
		for(Employee e:filterEmployeesSalary) {
			System.out.println(e);
		}
		
		System.out.println("优化方式1:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployeeByAge = filterEmployee(employees,new FilterEmployeeByAge());
		for(Employee e:filterEmployeeByAge) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeeBySalary = filterEmployee(employees,new FilterEmployeeBySalary());
		for(Employee e:filterEmployeeBySalary) {
			System.out.println(e);
		}
	}
}

4)、运行效果:

获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式1:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]

5)、分析上述代码的优缺点

那么这么做的好处是什么呢?我们这里的方法只指向一个,即在实现中,只有一个filterEmployee方法,而具体需要对比哪个字段大的值,只需要传递进来相应的MyPredicate接口参数即可!也即是说,选择相应的MyPredicate接口实现类作为参数就可以控制比较的字段!

如果你想按年龄进行过滤,那就将FilterEmployeeByAge类的实例作为参数传递进来;

如果你想按工资进行过滤,那就将FilterEmployeeBySalary类的实例作为参数传递进来;

这样的话,如果新增一个需求,要求按照其他字段进行过滤的话,那么我们只需要编写一个

MyPredicate接口的实现类,在实现类中进行具体逻辑的实现即可!

这个即使优点,同时也是缺点!因为没增加一个需求,都需要编写一个实现类,其实也是很不友好的!

但是目前来说,这基本上也就是最好的一种优化方式了!

4、使用匿名内部类的方式,对上述代码进行优化

1)、代码实现(接口不变)

package 为什么要使用lambad表达式;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import 为什么要使用lambad表达式.entity.Employee;
import 为什么要使用lambad表达式.inter.MyPredicate;
import 为什么要使用lambad表达式.inter.impl.FilterEmployeeByAge;
import 为什么要使用lambad表达式.inter.impl.FilterEmployeeBySalary;

/**
 * 演示为什么要引入lambad表达式2
 * 如果演示案例1还不足以说明lambad的好处,
 * 那么我们使用案例演示2来尝试说明lambad的好处!
 * 
 * 在这里我们提出一个明确的需求:
 * 获取当前公司中员工年龄大于35岁的员工信息!
 * 
 * @author yangbao
 */
public class LambadImport2 {
	
	//创建数据
	private static List<Employee> employees = Arrays.asList(
			new Employee("张三",18,9999.99),
			new Employee("李四",38,5555.55),
			new Employee("王五",50,6666.66),
			new Employee("赵六",16,3333.33),
			new Employee("田七", 8,7777.77)
	);
	

	/**
	 * 获取当前公司中员工年龄大于35岁的员工信息!
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployees(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getAge()>=35) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 获取当前公司中员工工资大于5000的员工信息
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployeesSalary(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getSalary()>=5000) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 优化方式1
	 * @param employeesList
	 * @param mp
	 * @return
	 */
	public static List<Employee> filterEmployee(List<Employee> employeesList,MyPredicate<Employee> mp){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee e:employeesList) {
			if(mp.compare(e)) {
				emps.add(e);
			}
		}
		return emps;
	}
	
	
	public static void main(String[] args) {
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployees = filterEmployees(employees);
		for(Employee e:filterEmployees) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeesSalary = filterEmployeesSalary(employees);
		for(Employee e:filterEmployeesSalary) {
			System.out.println(e);
		}
		
		System.out.println("优化方式1,使用策略模式对其进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployeeByAge = filterEmployee(employees,new FilterEmployeeByAge());
		for(Employee e:filterEmployeeByAge) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeeBySalary = filterEmployee(employees,new FilterEmployeeBySalary());
		for(Employee e:filterEmployeeBySalary) {
			System.out.println(e);
		}
		
		System.out.println("优化方式2,使用匿名内部类的方式,对上述代码进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> earlyUseOfAnonymousInnerClassesByAgeList = filterEmployee(employees,new MyPredicate<Employee>() {
			@Override
			public boolean compare(Employee t) {
				return t.getAge()>=35;
			}
		});
		for(Employee e:earlyUseOfAnonymousInnerClassesByAgeList) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> earlyUseOfAnonymousInnerClassesListBySalaryList = filterEmployee(employees,new MyPredicate<Employee>() {
			@Override
			public boolean compare(Employee t) {
				return t.getSalary()>=5000;
			}
		});
		for(Employee e:earlyUseOfAnonymousInnerClassesListBySalaryList) {
			System.out.println(e);
		}
	}
}

2)、运行效果:

获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式1,使用策略模式对其进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式2,使用匿名内部类的方式,对上述代码进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]

3)、分析上述代码的优缺点

优点:从上述实现的代码来看,我们不再需要创建实现类了,而是在匿名内部类中对具体的逻辑进行处理!

缺点:我们前面演示过使用匿名内部类来对比lambad表达式,那个时候我们是不是说过,其实这个匿名内部类中,实际上起作用的代码,就是实现方法中的内容,其余的全部没有用,只是一个架子而已!那么这个时候,我们就可以使用lambad表达式来对其进行优化了!

5、使用lambad表达式,对上述代码进行优化

1)、代码实现

package 为什么要使用lambad表达式;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import 为什么要使用lambad表达式.entity.Employee;
import 为什么要使用lambad表达式.inter.MyPredicate;
import 为什么要使用lambad表达式.inter.impl.FilterEmployeeByAge;
import 为什么要使用lambad表达式.inter.impl.FilterEmployeeBySalary;

/**
 * 演示为什么要引入lambad表达式2
 * 如果演示案例1还不足以说明lambad的好处,
 * 那么我们使用案例演示2来尝试说明lambad的好处!
 * 
 * 在这里我们提出一个明确的需求:
 * 获取当前公司中员工年龄大于35岁的员工信息!
 * 
 * @author yangbao
 */
public class LambadImport2 {
	
	//创建数据
	private static List<Employee> employees = Arrays.asList(
			new Employee("张三",18,9999.99),
			new Employee("李四",38,5555.55),
			new Employee("王五",50,6666.66),
			new Employee("赵六",16,3333.33),
			new Employee("田七", 8,7777.77)
	);
	

	/**
	 * 获取当前公司中员工年龄大于35岁的员工信息!
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployees(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getAge()>=35) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 获取当前公司中员工工资大于5000的员工信息
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployeesSalary(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getSalary()>=5000) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 优化方式1
	 * @param employeesList
	 * @param mp
	 * @return
	 */
	public static List<Employee> filterEmployee(List<Employee> employeesList,MyPredicate<Employee> mp){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee e:employeesList) {
			if(mp.compare(e)) {
				emps.add(e);
			}
		}
		return emps;
	}
	
	
	public static void main(String[] args) {
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployees = filterEmployees(employees);
		for(Employee e:filterEmployees) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeesSalary = filterEmployeesSalary(employees);
		for(Employee e:filterEmployeesSalary) {
			System.out.println(e);
		}
		
		System.out.println("优化方式1,使用策略模式对其进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployeeByAge = filterEmployee(employees,new FilterEmployeeByAge());
		for(Employee e:filterEmployeeByAge) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeeBySalary = filterEmployee(employees,new FilterEmployeeBySalary());
		for(Employee e:filterEmployeeBySalary) {
			System.out.println(e);
		}
		
		System.out.println("优化方式2,使用匿名内部类的方式,对上述代码进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> earlyUseOfAnonymousInnerClassesByAgeList = filterEmployee(employees,new MyPredicate<Employee>() {
			@Override
			public boolean compare(Employee t) {
				return t.getAge()>=35;
			}
		});
		for(Employee e:earlyUseOfAnonymousInnerClassesByAgeList) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> earlyUseOfAnonymousInnerClassesListBySalaryList = filterEmployee(employees,new MyPredicate<Employee>() {
			@Override
			public boolean compare(Employee t) {
				return t.getSalary()>=5000;
			}
		});
		for(Employee e:earlyUseOfAnonymousInnerClassesListBySalaryList) {
			System.out.println(e);
		}
		
		System.out.println("优化方式3,使用lambad表达式,对上述代码进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> lambadByAgeList = filterEmployee(employees,(e)->e.getAge()>=35);
		lambadByAgeList.forEach(System.out::println);

		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> lambadBySalaryList = filterEmployee(employees,(e)->e.getSalary()>=5000);
		lambadBySalaryList.forEach(System.out::println);
		
	}
}

2)、运行效果

获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式1,使用策略模式对其进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式2,使用匿名内部类的方式,对上述代码进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式3,使用lambad表达式,对上述代码进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]

3)、分析上述代码的优缺点

优点:上述代码,基本上已经将策略模式精简到了极致了,但是,优点就不言而喻了吧!

缺点:还是有人会不满意,那么没关系,我们再往下看!

6、使用stream,对上述代码进行优化

1)、代码实现

package 为什么要使用lambad表达式;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import 为什么要使用lambad表达式.entity.Employee;
import 为什么要使用lambad表达式.inter.MyPredicate;
import 为什么要使用lambad表达式.inter.impl.FilterEmployeeByAge;
import 为什么要使用lambad表达式.inter.impl.FilterEmployeeBySalary;

/**
 * 演示为什么要引入lambad表达式2
 * 如果演示案例1还不足以说明lambad的好处,
 * 那么我们使用案例演示2来尝试说明lambad的好处!
 * 
 * 在这里我们提出一个明确的需求:
 * 获取当前公司中员工年龄大于35岁的员工信息!
 * 
 * @author yangbao
 */
public class LambadImport2 {
	
	//创建数据
	private static List<Employee> employees = Arrays.asList(
			new Employee("张三",18,9999.99),
			new Employee("李四",38,5555.55),
			new Employee("王五",50,6666.66),
			new Employee("赵六",16,3333.33),
			new Employee("田七", 8,7777.77)
	);
	

	/**
	 * 获取当前公司中员工年龄大于35岁的员工信息!
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployees(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getAge()>=35) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 获取当前公司中员工工资大于5000的员工信息
	 * @param employees
	 * @return
	 */
	public static List<Employee> filterEmployeesSalary(List<Employee> employees){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee emp:employees) {
			if(emp.getSalary()>=5000) {
				emps.add(emp);
			}
		}
		return emps;
	}
	
	
	/**
	 * 优化方式1
	 * @param employeesList
	 * @param mp
	 * @return
	 */
	public static List<Employee> filterEmployee(List<Employee> employeesList,MyPredicate<Employee> mp){
		List<Employee> emps = new ArrayList<Employee>();
		for(Employee e:employeesList) {
			if(mp.compare(e)) {
				emps.add(e);
			}
		}
		return emps;
	}
	
	
	public static void main(String[] args) {
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployees = filterEmployees(employees);
		for(Employee e:filterEmployees) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeesSalary = filterEmployeesSalary(employees);
		for(Employee e:filterEmployeesSalary) {
			System.out.println(e);
		}
		
		System.out.println("优化方式1,使用策略模式对其进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> filterEmployeeByAge = filterEmployee(employees,new FilterEmployeeByAge());
		for(Employee e:filterEmployeeByAge) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> filterEmployeeBySalary = filterEmployee(employees,new FilterEmployeeBySalary());
		for(Employee e:filterEmployeeBySalary) {
			System.out.println(e);
		}
		
		System.out.println("优化方式2,使用匿名内部类的方式,对上述代码进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> earlyUseOfAnonymousInnerClassesByAgeList = filterEmployee(employees,new MyPredicate<Employee>() {
			@Override
			public boolean compare(Employee t) {
				return t.getAge()>=35;
			}
		});
		for(Employee e:earlyUseOfAnonymousInnerClassesByAgeList) {
			System.out.println(e);
		}
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> earlyUseOfAnonymousInnerClassesListBySalaryList = filterEmployee(employees,new MyPredicate<Employee>() {
			@Override
			public boolean compare(Employee t) {
				return t.getSalary()>=5000;
			}
		});
		for(Employee e:earlyUseOfAnonymousInnerClassesListBySalaryList) {
			System.out.println(e);
		}
		
		System.out.println("优化方式3,使用lambad表达式,对上述代码进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		List<Employee> lambadByAgeList = filterEmployee(employees,(e)->e.getAge()>=35);
		lambadByAgeList.forEach(System.out::println);

		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		List<Employee> lambadBySalaryList = filterEmployee(employees,(e)->e.getSalary()>=5000);
		lambadBySalaryList.forEach(System.out::println);
		
		System.out.println("优化方式4,使用stream语法,对上述代码进行优化:");
		System.out.println("获取当前公司中员工年龄大于35岁的员工信息:");
		employees.stream().filter((e)->e.getAge()>=35).forEach(System.out::println);
		
		System.out.println("获取当前公司中员工工资大于5000的员工信息:");
		employees.stream().filter((e)->e.getSalary()>=5000).forEach(System.out::println);
	}
}

2)、运行效果

获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式1,使用策略模式对其进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式2,使用匿名内部类的方式,对上述代码进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式3,使用lambad表达式,对上述代码进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]
优化方式4,使用stream语法,对上述代码进行优化:
获取当前公司中员工年龄大于35岁的员工信息:
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
获取当前公司中员工工资大于5000的员工信息:
Employee [name=张三, age=18, salary=9999.99]
Employee [name=李四, age=38, salary=5555.55]
Employee [name=王五, age=50, salary=6666.66]
Employee [name=田七, age=8, salary=7777.77]

3)、分析上述代码的优缺点

优点:代码及其简洁

缺点:需要学习

三、lambad表达式基础语法

1、lambad基础语法概述

Java8中引入了一个新的操作符“->”,该操作符称为箭头操作符或者lambad操作符,箭头操作符将整个lambad表达式拆分成了两个部分,分别是箭头左侧的部分和箭头右侧的部分:

1)、箭头左侧的部分

左侧部分为lambad表达式的参数列表!

2)、箭头右侧的部分

右侧部分为lambad体,该部分为lambad具体要执行的逻辑代码!

我们通过上述的演示案例和语法概念,可以总结出来,所谓的lambad表达式,就是一种对接口的实现的简易写法!

public interface MyPredicate<T>{
	//比较函数
	Public Boolean compare(T t);
}

如上图所示,我们lambad左侧的参数列表,指的就是这个接口中方法的参数列表,要求与之一一对应;而右侧的lambad体,指的就是实现类中该方法的实现中的逻辑代码,见下图中代码的蓝色部分:

package 为什么要使用lambad表达式.inter.impl;

 

import 为什么要使用lambad表达式.entity.Employee;

import 为什么要使用lambad表达式.inter.MyPredicate;

 

public class FilterEmployeeByAge implements MyPredicate<Employee> {

 

     /**

      * 实现比较函数

      */

     @Override

     public boolean compare(Employee t) {

         return t.getAge()>=35;

     }

}

最后,我们结合语法和业务逻辑,便可实现一个lambad表达式:

List<Employee> lambadByAgeList = filterEmployee(employees,(e)->e.getAge()>=35);

那么这个时候我们就会有一个疑问,既然lambad表达式要对接口中的抽象方法做实现,那么他具体要实现哪个抽象方法呢?

这个问题,就需要一个函数式接口来对其进行支持,那么什么是函数式接口呢?就是一个接口中,只有一个抽象方法!这个我们后面再说,这里先记一下这个点!

我们先简单的了解lambad语法的几种变换格式;

四、lambad语法的几种格式

这里再次强调一点,lambad表达式是对接口中的抽象类做具体实现的!

而我们接口中的抽象类,有很多种形式,有无惨的,有有参数的,有多参数的,有带返回值的,有不带返回值的,等等!

我们来了解一下lambad表达式对这几种抽象类的实现时什么样子的!

1、无参无返回值

我们知道Runnable接口就符合这样的条件,我们以Runnable接口为例来进行演示:

1)、代码实现:

package lambad表达式基础语法;

 

public class TestLambad1 {

 

    public static void main(String[] args) {

        System.out.println("调用原始实现方式");

        originalImplementation();

        System.out.println("调用lambad实现方式");

        lambadlImplementation();

    }

   

    /**

     * 原始实现方式

     */

    public static void originalImplementation() {

        Runnable r = new Runnable() {

            @Override

            public void run() {

                System.out.println("hello world");

               

            }

        };

        r.run();

    }

   

    /**

     * lambad实现方式

     */

    public static void lambadlImplementation() {

        Runnable r = ()->System.out.println("hello lambad");

        r.run();

    }

}

2)、运行效果:

调用原始实现方式

hello world

调用lambad实现方式

hello lambad

3)、总结:

Runnable r = () -> System.out.println("hello lambad");

红色部分为方法的返回值;

蓝色部分为接口中的抽象方法的参数列表;

绿色部分为lambad符号;

褐色部分为接口中的抽象方法的实现逻辑代码;

4)、注意事项

在局部内部类中使用到了同级别的局部变量的时候:

在jdk1.8以前,这个变量必须显式的声明为final类型的,但是在jdk1.8以后,无需显式的将其声明为final类型的,但是他本质上还是一个final类型的,他的值,不可以改变!

正确用法:

public static void originalImplementation() {

         int num = 0;

         Runnable r = new Runnable() {

              @Override

              public void run() {

                   System.out.println("hello world"+num);

                  

              }

         };

         r.run();

     }

错误用法:

     public static void originalImplementation() {

         int num = 0;

         Runnable r = new Runnable() {

              @Override

              public void run() {

                   System.out.println("hello world"+num++);

                  

              }

         };

         r.run();

     }

同样的,lambad也需要遵循这样的原则:

正确使用:

    public static void lambadlImplementation() {

        int num = 0;

        Runnable r = ()->System.out.println("hello lambad"+num);

        r.run();

    }

错误使用:

    public static void lambadlImplementation() {

        int num = 0;

        Runnable r = ()->System.out.println("hello lambad"+num++);

        r.run();

    }

2、有一个参数,并且无返回值

1)、代码实现

package lambad表达式基础语法;

import java.util.function.Consumer;

public class TestLambad1 {

     public static void main(String[] args) {

         lambadlImplementation2();

     }

     public static void lambadlImplementation2() {

         Consumer<String> con = (x)->System.out.println(x);

         con.accept("你好杨保"); 

     }

}

2)、运行效果

你好杨保

3)、总结

Consumer<String> con = (x)->System.out.println(x);

红色部分:方法的返回值;

蓝色部分:参数列表,其中x可以为任何字符串;

绿色部分:lambad符号;

褐色部分:方法的实现逻辑代码;

3、如接口中的抽象方法只有一个参数,那么lambad中的参数列表里的小括号可以不写

1)、代码实现

package lambad表达式基础语法;

import java.util.function.Consumer;

public class TestLambad1 {

     public static void main(String[] args) {

         lambadlImplementation3();

     }

     public static void lambadlImplementation3() {

         Consumer<String> con = x->System.out.println(x);

         con.accept("你好杨保");

     }

}

2)、运行效果

你好杨保

3)、总结

Consumer<String> con = x->System.out.println(x);

红色部分:方法的返回值;

蓝色部分:参数列表,其中x可以为任何字符串;如果方法的参数只有一个,小括号可以忽略不写;

绿色部分:lambad符号;

褐色部分:方法的实现逻辑代码;

4、一个以上参数,有返回值,并且lambad体中包含多条语句

1)、代码实现

package lambad表达式基础语法;

import java.util.Comparator;

import java.util.function.Consumer;

public class TestLambad1 {

     public static void main(String[] args) {

         lambadlImplementation4();

     }

     public static void lambadlImplementation4() {

         Comparator<Integer> com = (x,y)->{

              System.out.println("函数式接口");

              return Integer.compare(x, y);

         };

         int res = com.compare(1,2);

         System.out.println(res);

     }

}

2)、运行效果

函数式接口

-1

3)、总结

Comparator<Integer> com = (x,y)->{

    System.out.println("函数式接口");

    return Integer.compare(x, y);

};

红色部分:接口的实例对象;

蓝色部分:接口中抽象方法的参数列表,其中x,y类似于占位符,写什么字符串放在这里都可以;

绿色部分:lambad符号;

褐色部分:接口中抽象方法的实现逻辑代码,如果该实现逻辑需要多行代码,那么必须使用大括号对其进行包裹!

5、若lambad中只有一条语句,那么return和大括号都可以省略

1)、代码实现

package lambad表达式基础语法;

import java.util.Comparator;

import java.util.function.Consumer;

public class TestLambad1 {

     public static void main(String[] args) {

         lambadlImplementation5();

     }

    

     public static void lambadlImplementation5() {

         Comparator<Integer> com = (x,y)->Integer.compare(x, y);

         int res = com.compare(1,2);

         System.out.println(res);

     }   

}

2)、运行效果

-1

3)、总结

Comparator<Integer> com = (x,y)->Integer.compare(x, y);

红色部分:接口的实例对象;

蓝色部分:接口中抽象方法的参数列表,如果只有一个参数的话,小括号可以省略;

绿色部分:lambad符号;

褐色部分:接口中抽象方法的实现逻辑代码,如果该方法需要返回值,并且lambad中只有一句代码,那么return可以省略不写,同时{}大括号也可以省略不写;

6、参数推导

Lambad表达式的参数列表的数据类型可以省略不写,因为JVM编译器可以通过上下文推断出数据类型,即:参数推断;

1)、代码实现

package lambad表达式基础语法;

 

import java.util.Comparator;

import java.util.function.Consumer;

 

public class TestLambad1 {

 

     public static void main(String[] args) {

         lambadlImplementation6();

     }

     public static void lambadlImplementation6() {

         Comparator<Integer> com = (Integer x,Integer y)->Integer.compare(x, y);

         int res = com.compare(1,2);

         System.out.println(res);

     }

}

2)、运行效果

-1

3)、总结

Comparator<Integer> com = (Integer x,Integer y)->Integer.compare(x, y);

红色部分:方法的返回值;

蓝色部分:参数列表,其中x可以为任何字符串;如果方法的参数只有一个,小括号可以忽略不写;这里是写全了的样子,是可以加上参数类型的;

绿色部分:lambad符号;

褐色部分:方法的实现逻辑代码;

五、lambad表达式与接口关系

1、函数式接口的支持

我们前面说过,lambad是对接口中的方法进行实现,并且接口中的方法还不能多,多了就区分不了了,那么针对这个地方,我们给与解释说明;

首先,lambad需要函数式接口的支持,那么什么是函数式接口呢?

若接口中只有一个抽象方法的接口,那么我们就称其为函数式接口;

我们可以使用注解@FunctionalInterface标注某个接口为函数式接口;

使用该注解之后,可以对该接口进行检查,检查其是否为函数式接口;

其实,这就是lambad的限制条件;

备足:lambad+策略模式,是一种非常友好的实现之一;

六、lambad表达式小练习

1、调用collections.sort()方法,通过定制排序比较两个employee(先按年龄比,年龄相同按姓名比),使用lambad作为参数传递;

1)、代码实现

package 联系题;

 

import java.util.Arrays;

import java.util.Collections;

import java.util.List;

import 为什么要使用lambad表达式.entity.Employee;

 

public class TestLambad {

 

    

     //创建数据

     private static List<Employee> employeesList = Arrays.asList(

              new Employee("张三",18,9999.99),

              new Employee("李四",38,5555.55),

              new Employee("王五",50,6666.66),

              new Employee("赵六",16,3333.33),

              new Employee("田七", 8,7777.77)

     );

    

     public static void test1() {

         Collections.sort(employeesList, (e1,e2)->{

              if(e1.getAge()==e2.getAge()) {

                   return e1.getName().compareTo(e2.getName());

              }else {

                   return Integer.compare(e1.getAge(),e2.getAge());

              }

         });

     }

 

     public static void main(String[] args) {

         test1();

         employeesList.forEach(e->System.out.println(e));

     }

}

2)、运行效果:

Employee [name=田七, age=8, salary=7777.77]

Employee [name=赵六, age=16, salary=3333.33]

Employee [name=张三, age=18, salary=9999.99]

Employee [name=李四, age=38, salary=5555.55]

Employee [name=王五, age=50, salary=6666.66]

2、自定义练习题1

声明一个带有两个泛型的函数式接口,泛型为<T,R>,T为参数,R为返回值;

接口中声明抽象方法;

在TestLambad类中声明方法,使用接口作为参数,计算两个long类型参数的和;

再计算两个long类型参数的积;

1)、代码实现

package 联系题;

 

import java.util.Arrays;

import java.util.Collections;

import java.util.List;

import 为什么要使用lambad表达式.entity.Employee;

import 联系题.inter.MyFun;

import 联系题.inter.MyFunction;

 

public class TestLambad {

     public static void test3() {

         Long longHadnler1 = longHadnler(100l,200l,(l1,l2)->l1+l2);

         System.out.println(longHadnler1);

         Long longHadnler2 = longHadnler(100l,200l,(l1,l2)->l1*l2);

         System.out.println(longHadnler2);

     }

    

    

     /**

      * 对两个泛型数据进行处理

      * @param str

      * @param mf

      * @return

      */

     public static Long longHadnler(Long l1,Long l2,MyFun<Long,Long> mf) {

         return mf.getValue(l1,l2);

     }

    

    

     public static void main(String[] args) {

         test3();

     }

}

2)、运行效果

300

20000

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java 8引入了lambda表达式作为一种的编程语言特性。lambda表达式是一种匿名函数,它可以作为参数传递给方法或存储在变量中。它可以简化代码,使代码更加易读和易维护。lambda表达式的语法非常简洁,可以用来替代匿名内部类。它可以在集合框架中使用,使代码更加简洁和易读。lambda表达式Java 8中最重要的特性之一,它使Java编程更加现代化和高效。 ### 回答2: Lambda 表达式Java 8 中最重要的特性之一,它可以让我们以更简洁的方式来编写代码,并且能够更优雅的解决许多问题。 Lambda 表达式本身是一个匿名函数,它可以被当做对象进行传递和处理。它强调的是函数式编程思想,将函数作为一等公民,并支持灵活的函数组合。Lambda 表达式通常由左侧的参数列表、箭头符号和右侧的函数体组成。例如: ``` (x, y) -> x + y ``` 上述代码定义了一个 lambda 表达式,这个表达式接受两个参数 x 和 y,然后返回它们的和。 Lambda 表达式的用途非常广泛,它们通常用于简化代码,比如用于普通的遍历集合和数组: ``` List<String> names = Arrays.asList("alice", "bob", "charlie"); names.forEach(name -> System.out.println(name)); ``` Lambda 表达式还可以用于函数式接口,这是一种只包含一个抽象方法的接口。函数式接口可以被当做 lambda 表达式的类型,这意味着我们可以使用 lambda 表达式来创建这种类型的对象。例如: ``` interface Calculator { int calculate(int a, int b); } Calculator add = (a, b) -> a + b; Calculator sub = (a, b) -> a - b; ``` 上述代码定义了一个接口类型 Calculator,它包含一个抽象方法 calculate,并且使用 lambda 表达式来定义 add 和 sub 两个对象,它们分别代表加法和减法。 Lambda 表达式还支持方法引用,这是一种更简洁的语法形式,它允许我们使用方法名来代替 lambda 表达式的函数体。例如: ``` List<String> names = Arrays.asList("alice", "bob", "charlie"); names.forEach(System.out::println); ``` 上述代码使用了方法引用,它代替了之前的 lambda 表达式。 总之,Java 8 的 Lambda 表达式是一项非常有用的功能,它提供了一种更简单的方式来编写代码,让我们的代码更加简约且易于阅读。同时,它也是一种函数式编程思想的体现,让 Java 开发者能够更好的应用这些思想来解决实际问题。 ### 回答3: Java8的lambda表达式是一个Java编程语言的特性,它可以方便地为函数式接口创建实例。Lambda表达式允许你直接以更加简单和精简的方式来定义内部类,并且能够省略掉那些没有用的代码。 在Java 8中,Lambda表达式通过一个箭头“->”来定义。在箭头左边是参数列表,这些参数可以是任何类型,但是Lambda表达式中只能有一个方法参数。在箭头右边是Lambda表达式的主体,也就是这个Lambda表达式所要执行的代码块。 Lambda表达式还可以访问外部作用域中的变量,这是通过捕获变量的方式来实现的。Lambda表达式在使用外部变量时会将其捕获到Lambda表达式内部,从而形成一个闭包,这使得Lambda表达式能够访问外部的变量。 Lambda表达式的使用能够使得代码更加简洁,能够将代码逻辑更加清晰地表达。在Java8中,Lambda表达式被广泛应用于集合的处理,比如通过对集合进行排序、过滤、映射等操作,能够更加简单地处理数据集合。Lambda表达式还被应用于多线程的编程中,能够使得并发编程更加方便和简单。 总之,Java 8的Lambda表达式是一个很有用的特性。它能够使得Java代码更加简洁和易于理解,减少了冗余的结构和语法。同时,它也提供了更加灵活的编程方式,使得Java编程能够更加高效和便利。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值