Lambda是一个匿名函数,可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递),可以写出更简洁、更灵活的代码,作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。
package com.alisa.java8;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class LambdaTest1 {
//原来的匿名内部类
@Test
public void test1(){
Comparator<String> com = new Comparator<String>() {
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
};
TreeSet<String> treeSet = new TreeSet<>(com);
TreeSet<String> treeSet1 = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
});
}
//Lambda表达式
@Test
public void test2(){
Comparator<String> com = (x,y) -> Integer.compare(x.length(),y.length());
TreeSet<String> treeSet = new TreeSet<>(com);
}
List<Employee> emps = Arrays.asList(
new Employee(101, "张三", 18, 9999.99),
new Employee(102, "李四", 59, 6666.66),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
//需求1:获取公司中年龄小于35的员工
public List<Employee> filterEmployeeByAge(List<Employee> list){
List<Employee> emps = new ArrayList<>();
for (Employee emp:list) {
if(emp.getAge() < 35){
emps.add(emp);
}
}
return emps;
}
@Test
public void test3(){
List<Employee> employees = filterEmployeeByAge(emps);
for (Employee emp: employees) {
System.out.println(emp);
}
}
//需求2:获取公司中工资大于5000的员工
public List<Employee> filterEmployeeBySalary(List<Employee> list){
List<Employee> emps = new ArrayList<>();
for (Employee emp: list) {
if(emp.getSalary() > 5000)
emps.add(emp);
}
return emps;
}
@Test
public void test4(){
List<Employee> employees = filterEmployeeBySalary(emps);
for (Employee emp: employees) {
System.out.println(emp);
}
}
//以上两个需求实现方式繁琐,且有大量重复操作,优化方式如下:
//优化方式1:策略设计模式
public List<Employee> filterEmployee(List<Employee> list, EmployeePredicate<Employee> ep){
List<Employee> emps = new ArrayList<>();
for (Employee emp : list) {
if(ep.test(emp)){
emps.add(emp);
}
}
return emps;
}
@Test
public void test5(){
List<Employee> employees = filterEmployee(emps, new FilterEmployeeByAge());
for (Employee emp: employees) {
System.out.println(emp);
}
System.out.println("========================================");
List<Employee> employees1 = filterEmployee(emps,new FilterEmployeeBySalary());
for (Employee emp: employees1) {
System.out.println(emp);
}
}
//优化方式2:匿名内部类
@Test
public void test6(){
List<Employee> employeesByAge = filterEmployee(emps, new EmployeePredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getAge() < 35;
}
});
for (Employee emp: employeesByAge) {
System.out.println(emp);
}
System.out.println("========================================");
List<Employee> employeesBySalary = filterEmployee(emps, new EmployeePredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getSalary() > 5000;
}
});
for (Employee emp: employeesBySalary) {
System.out.println(emp);
}
}
//优化方式3:Lambda表达式
@Test
public void test7(){
List<Employee> employeesByAge = filterEmployee(emps,(employee -> employee.getAge() < 35));
employeesByAge.forEach(System.out::println);
System.out.println("========================================");
List<Employee> employeesBySalary = filterEmployee(emps, (employee -> employee.getSalary() > 5000));
employeesBySalary.forEach(System.out::println);
}
//优化方式4:Stream API
@Test
public void test8(){
emps.stream().filter(employee -> employee.getAge() < 35).forEach(System.out::println);
System.out.println("========================================");
emps.stream().filter(employee -> employee.getSalary() > 5000).forEach(System.out::println);
}
}
package com.alisa.java8;
public class Employee {
private int id;
private String name;
private int age;
private double salary;
public Employee() {
}
public Employee(String name) {
this.name = name;
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public Employee(int id, String name, int age, double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String show() {
return "测试方法引用!";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(salary);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (age != other.age)
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))
return false;
return true;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + "]";
}
}
package com.alisa.java8;
@FunctionalInterface
public interface EmployeePredicate<T> {
boolean test(T t);
}
package com.alisa.java8;
public class FilterEmployeeByAge implements EmployeePredicate<Employee>{
@Override
public boolean test(Employee employee) {
return employee.getAge() < 35;
}
}
package com.alisa.java8;
public class FilterEmployeeBySalary implements EmployeePredicate<Employee>{
@Override
public boolean test(Employee employee) {
return employee.getSalary() > 5000;
}
}
package com.alisa.java8;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Comparator;
import java.util.function.Consumer;
/*
* 一、Lambda表达式的基础语法:Java8中引入了一个新的操作符"->",该操作符被称为箭头操作符或Lambda操作符
* 它将Lambda表达式分为两部分:
* 左侧:指定了Lambda表达式需要的所有参数
* 右侧:指定了Lambda体,即Lambda表达式要执行的功能
*
* 语法格式一:无参数、无返回值
* () -> System.out.println("Hello Lambda");
*
* 语法格式二:有一个参数,并且无返回值,若只有一个参数,小括号可以省略不写
* (x) -> System.out.println(x);
*
* 语法格式三:有两个及以上的参数,有返回值,并且Lambda体中有多条语句
* Lambda体中只有一条语句,return和大括号都可以省略不写
* Comparator<Integer> com = (x,y) -> {
* System.out.println("函数式接口");
* return Integer.compare(x,y);
* };
*
* 语法格式四:Lambda表达式的参数列表的数据类型可以省略不写,
* 因为JVM编译器通过上下文推断出数据类型
* (String x,String y) -> Integer.compare(x.length(),y.length());
*
* 二、Lambda表达式需要“函数式接口”的支持
* 函数式接口:接口中只有一个抽象方法的接口,可以使用注解@FunctionalInterface修饰
* EmployeePredicate接口就是函数式接口
* */
@RunWith(SpringRunner.class)
@SpringBootTest
public class LambdaTest2 {
@Test
public void test1(){
Runnable r = () -> System.out.println("Hello Lambda");
r.run();
}
@Test
public void test2(){
Consumer<String> com = (x) -> System.out.println(x);
com.accept("Hello Lambda");
System.out.println("===========================");
Consumer<String> com1 = x -> System.out.println(x);
com1.accept("Hello World");
}
@Test
public void test3(){
Comparator<Integer> com = (x,y) -> {
System.out.println("函数式接口");
return Integer.compare(x,y);
};
System.out.println(com.compare(7,5));
}
@Test
public void test4(){
Comparator<String> com = (String x,String y) -> Integer.compare(x.length(),y.length());
System.out.println(com.compare("Lambda","World"));
}
//需求:对一个数进行运算,创建函数式接口—
@Test
public void test5(){
Integer num = operation(10,(x) -> x * x);
System.out.println(num);
System.out.println(operation(2,(x) -> x+7));
}
public Integer operation(Integer num,OperationFunction of){
return of.operation(num);
}
}
package com.alisa.java8;
@FunctionalInterface
public interface OperationFunction {
Integer operation(Integer num);
}
package com.alisa.java8;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
@RunWith(SpringRunner.class)
@SpringBootTest
/*
* Java8内置四大核心函数式接口
*
* 1、Consumer<T>:消费型接口—void accept(T t);
*
* 2、Supplier<T>:供给型接口—T get();
*
* 3、Function<T,R>:函数型接口—R apply(T t);
*
* 4、Predicate<T>:断言型接口—boolean test(T t);
* */
public class LambdaTest3 {
//Consumer<T>消费型接口
@Test
public void test1(){
consume(1000.0,(money) -> System.out.println("消费"+money+"元"));
}
public void consume(Double money, Consumer<Double> con){
con.accept(money);
}
//Supplier<T>供给型接口,产生指定个数的整数,并放入集合
@Test
public void test2(){
List<Integer> numList = getNumList(8,() -> (int)(Math.random()*100));
numList.forEach(System.out::println);
}
public List<Integer> getNumList(int num,Supplier<Integer> sup){
List<Integer> numList = new ArrayList<>();
for(int i=0; i<num; i++){
numList.add(sup.get());
}
return numList;
}
//Function<T,R>函数型接口,用于处理字符串
@Test
public void test3(){
String str = handle("\t\t\t Lambda ",(s) -> s.trim());
System.out.println(str);
}
public String handle(String str, Function<String,String> fun){
return fun.apply(str);
}
//Predicate<T>断言型接口,将满足条件的字符串放入集合中
@Test
public void test4(){
List<String> strList = Arrays.asList("qwe","dfer","wertg","fg");
List<String> resultList = filterStr(strList,(str) -> str.length() >= 3);
resultList.forEach(System.out::println);
}
public List<String> filterStr(List<String> strList, Predicate<String> pre){
List<String> list = new ArrayList<>();
for (String str:strList) {
if(pre.test(str))
list.add(str);
}
return list;
}
}
package com.alisa.java8;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ExerpiceLambda {
List<Employee> emps = Arrays.asList(
new Employee(101, "张三", 18, 9999.99),
new Employee(102, "李四", 59, 6666.66),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
/*
* 1、调用Collections.sort()方法,通过定制排序比较两个Employee(先按年龄比,
* 年龄相同按姓名比),使用Lambda作为参数传递
* */
@Test
public void test1() {
Collections.sort(emps,(e1,e2) -> {
if(e1.getAge() == e2.getAge()){
return e1.getName().compareTo(e2.getName());
}else{
return Integer.compare(e1.getAge(),e2.getAge());
}
});
emps.forEach(System.out::println);
}
/*
* 2、
* (1)声明函数式接口,接口中声明抽象方法,public String getValue(String str);
* (2)编写方法使用接口作为参数,将一个字符串转换成大写,并作为方法的返回值
* (3)再将这个字符串的第2个和第4个索引位置进行截取子串
* */
@Test
public void test2(){
List<String> strList = Arrays.asList("Lambda","Hello world","java8");
List<String> upperList = operationStr(strList,(str) -> str.toUpperCase());
upperList.forEach(System.out::println);
System.out.println("======================");
List<String> subList = operationStr(strList,(str) -> str.substring(2,5));
subList.forEach(System.out::println);
}
public List<String> operationStr(List<String> stringList,ExerpiceLambdaStr<String> els){
List<String> list = new ArrayList<>();
for (String str: stringList) {
list.add(els.getValue(str));
}
return list;
}
/*
* 3、
* (1)声明一个带两个泛型的函数式接口,泛型类型为<T,R>,T为参数,R为返回值
* (2)接口中声明对应的抽象方法
* (3)声明方法,使用接口作为参数,计算两个Long型参数的和
* (4)再计算两个Long型参数的乘积
* */
@Test
public void test3(){
Long sum = getValue(10L,2L,(x,y) -> x + y);
System.out.println(sum);
Long product = getValue(3L,4L,(x,y) -> x * y);
System.out.println(product);
}
public Long getValue(Long num1,Long num2,ExecpriceLambdaLong<Long,Long> el){
return el.getValue(num1,num2);
}
}
package com.alisa.java8;
@FunctionalInterface
public interface ExerpiceLambdaStr<T> {
String getValue(String str);
}
package com.alisa.java8;
@FunctionalInterface
public interface ExecpriceLambdaLong<T,R> {
Long getValue(Long num,Long num2);
}