JDK8(又称 JDK1.8) 是 JDK 的一个重要的长期支持版本(LTS),在生产环境中使用非常广泛。
JDK8 是由 Oracle 公司于 2014 年 3 月 18 日发布,支持函数式编程,新的 JavaScript 引擎,新的日期 API 以及新的 Stream API 等。
@FunctionalInterface
这个接口的修饰下,只能有一个抽象方法,也即在这个注释下的接口是一个函数式接口
package com.tao.lambda;
import com.tao.MyPredicate;
import com.tao.pojo.Employee;
import org.junit.Test;
import java.util.*;
public class TestLambda {
@Test
public void test1() {
//原来的匿名内部类
Comparator<Integer> com = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
TreeSet<Integer> ts = new TreeSet<>(com);
}
//lambda表达式
@Test
public void test2() {
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
TreeSet<Integer> ts = new TreeSet<>(com);
}
//需求:获取当前公司员工中年龄大于35的
List<Employee> employees = Arrays.asList(
new Employee("张三", 18, 998.1),
new Employee("李四", 12, 9983.1),
new Employee("王五", 53, 9928.1),
new Employee("赵六", 43, 1234.1),
new Employee("田七", 41, 7564.1)
);
public List<Employee> filterEmployee(List<Employee> list) {
List<Employee> emps = new ArrayList<>();
for (Employee emp : list) {
if (emp.getAge() > 35) {
emps.add(emp);
}
}
return emps;
}
//需求:获取公司中员工工资大于5000
//按传统方法
public List<Employee> filterEmployee2(List<Employee> list) {
List<Employee> emps = new ArrayList<>();
for (Employee emp : list) {
if (emp.getSalary() > 5000) {
emps.add(emp);
}
}
return emps;
}
@Test
public void test3() {
List<Employee> list = filterEmployee(employees);
for (Employee e : list
) {
System.out.println(e);
}
}
@Test
public void test4() {
List<Employee> list = filterEmployee2(employees);
for (Employee e : list
) {
System.out.println(e);
}
}
//优化方式:策略设计模式
@Test
public void test5() {
List<Employee> list = filterEmployee(employees, new FilterEmployeeByAge());
for (Employee employee : list
) {
System.out.println(employee);
}
}
public List<Employee> filterEmployee(List<Employee> employees, MyPredicate<Employee> mp) {
List<Employee> emps = new ArrayList<>();
for (Employee employee : employees
) {
if (mp.test(employee)) {
emps.add(employee);
}
}
return emps;
}
@Test
public void test6() {
List<Employee> list = filterEmployee(employees, new FilterEmployeeBySalary());
for (Employee employee : list
) {
System.out.println(employee);
}
}
public List<Employee> filterEmployee2(List<Employee> employees, MyPredicate<Employee> mp) {
List<Employee> emps2 = new ArrayList<>();
for (Employee employee : employees
) {
if (mp.test(employee)) {
emps2.add(employee);
}
}
return emps2;
}
//优化方式二: 匿名内部类
@Test
public void test7(){
List<Employee> list = filterEmployee(employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getSalary()< 5000;
}
});
for (Employee employ: list
) {
System.out.println(employ);
}
}
//优化方式三;lambda表达式,非常清爽
@Test
public void test8(){
List<Employee> list = filterEmployee(employees,(e)->e.getSalary()<5000);
list.forEach(System.out::println);
}
//优化方式四:
@Test
public void test9(){
employees.stream()
.filter((e)-> e.getSalary()>5000)
.limit(2)
.forEach(System.out::println);
System.out.println("--------------------");
// 将所有结果遍历出来
employees.stream()
.map(Employee::getName)
.forEach(System.out::println);
}
}
一 Lambda表达式的举出语法:Java8引入了一个新的操作符:"->"
改操作符成为箭头操作符或者Lambda操作符
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能,即Lambda体
语法格式1:无参数,无返回值
() -> System.out.pritln(" ")
语法格式2: 一个参数,无返回值
语法格式3:若只有一个参数,小括号可以省略不写
x-> System.out.println(x);
语法格式4: 有两个以上的参数,lambda体中有多个函数
注:多条语句的话,函数体要用{}
语法格式5: lambda体中只有一条语句,大括号和return都可以省略
语法格式6:lambda 表达式的参数列表的数据类型可以省略不屑,因为 JVM编译器通过上下午
推断出,数据类型,即"类型推断"
上:左右遇一括号省
下:左侧推断类型省
横批:能省则省
二 Lambda 表达式需要"函数式接口"的支持
函数式接口:接口中只有一个抽象方法的接口,称为函数式接口
可以使用@FunctionalInterface修饰一下
三、深入了解Lambda
package com.tao.lambda;
import org.junit.Test;
import java.lang.reflect.Array;
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;
/**
* Java8 内置的四大核心函数式接口
*
* Consumer 消费型 void accept(T t) >
*
* Supplier 提供型接口 T get()>
*
* Function 函数型接口 R apply(T t)>
*
* Predicate 断言型接口>
* boolean test(T t)
*/
public class TestLambda3 {
@Test
public void test1(){
happy(1000,m -> System.out.println("吉他花费"+m+"元"));
}
public void happy(double money, Consumer<Double> con){
con.accept(money);
}
@Test
public void test2(){
List<Integer> numList = getNumList(100, () -> (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;
}
@Test
public void test3(){
String s = strHandler("\t\t\ttcoderlearn\n", str -> str.trim());
System.out.println(s);
}
//需求:用于处理字符串
public String strHandler(String str, Function<String ,String>fun){
return fun.apply(str);
}
@Test
public void test4(){
List<String> list = Arrays.asList("hello","zitao","world","www","a");
List<String> strings = filterStr(list, s -> s.length() > 3);
for (String str:strings
) {
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;
}
}