一 :那么Lambda有什么长处 :
1、操作简单
2、代码优化
错误谬误 :
1、很是不易读
二:Lambda表达式的尺度格局为 : ( 参数类型 参数名称 ) -> { 代码语句 }
三:Lambda的利用前提-函数式接口
3.1、利用Lambda必需具有接口,且要求接口中有且仅有一个抽象方式。无论是JDK内置的Runnable、Comparator接口仍是自界说的接口,只有当接口中的抽象方式存在且独一时,才可以利用Lambda。
3.2、利用Lambda必需具有上下文揣度。也就是方式的参数或局部变量类型必需为Lambda对应的接口类型,才能利用Lambda作为该接口的实例。
初识lambda表达式:
package com.sgg.lambda;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import org.junit.Test;
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);
}
List<Employee> employees = Arrays.asList(new Employee("张三", 12, 1200.99), new Employee("小明", 15, 4500.99),
new Employee("小丽", 16, 5500.99), new Employee("王二", 32, 1100.99), new Employee("二虎", 22, 9825.99),
new Employee("李静", 18, 4502.99), new Employee("小三", 17, 1469.99));
// 需求获取当前公司中员工春秋大于16的员工信息
public List<Employee> filterEmployees(List<Employee> employees) {
List<Employee> emps = new ArrayList<Employee>();
for (Employee emp : employees) {
if (emp.getAge() > 16) {
emps.add(emp);
}
}
return emps;
}
// 需求获取当前公司中员工工资大于5000的员工信息
public List<Employee> filterEmployees2(List<Employee> employees) {
List<Employee> emps = new ArrayList<Employee>();
for (Employee emp : employees) {
if (emp.getSalary() > 5000) {
emps.add(emp);
}
}
return emps;
}
@Test
public void test3() {
List<Employee> emps = filterEmployees2(employees);
for (Employee emp : emps) {
System.out.println(emp);
}
}
// 优化体例一:利用设计模式-策略设计模式
public List<Employee> filterEmployee(List<Employee> employees, MyPredicate<Employee> mp) {
List<Employee> emps = new ArrayList<Employee>();
for (Employee emp : employees) {
if (mp.test(emp)) {
emps.add(emp);
}
}
return emps;
}
@Test
public void test4() {
// List<Employee> emps = filterEmployee(employees, new FilterEmployeeByAge());
List<Employee> emps = filterEmployee(employees, new FilterEmployeeBySalary());
for (Employee emp : emps) {
System.out.println(emp);
}
}
// 优化体例二:匿名内部类
@Test
public void test5() {
List<Employee> emps = filterEmployee(employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee t) {
return t.getAge() < 16;
}
});
for (Employee emp : emps) {
System.out.println(emp);
}
}
// 优化体例三:lambda表达式
@Test
public void test6() {
List<Employee> emps = filterEmployee(employees, (e) -> e.getAge() > 17);
for (Employee emp : emps) {
System.out.println(emp);
}
}
// 优化体例四:streamAPI
@Test
public void test7() {
employees.stream().filter((e) -> e.getAge() > 17).forEach(System.out::println);
employees.stream().map(Employee::getName).forEach(System.out::println);
}
}
Lambda表达式根本语法:
package com.sgg.lambda2;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.junit.Test;
/**
* 一 、Lambda 表达式的根本语法:java8中引入了一个新的操作符“->”改操作符称为箭头操作符或Lambda操作符
* 箭头操作符将Lambda表达式拆分当作两部门:
*
* 左侧:Lambda的参数列表 右侧:Lambda所需要执行的功能,即Lambda 体
*
* 语法格局一:无参数,无返回值 () -> System.out.println("hello lambda")
*
* 语法格局二:有一个参数,而且无返回值 (x) -> System.out.println(x)
*
* 语法格局三:有一个参数,而且无返回值,左侧的参数小括号可以省略不写。 x -> System.out.println(x)
*
* 语法格局四:有两个个以上参数,有返回值,而且Lambda 体 中有多条语句。 Comparator<Integer> com = (x,y) -> {
* System.out.println("函数式接口, 成果测试!"); return Integer.compare(x, y); };
*
* 语法格局五:若Lambda 体 中只有一条语句,大括号和return都可以省略。 Comparator<Integer> com2 = (x,y) ->
* Integer.compare(x, y);
*
* 语法格局六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器可以经由过程上下文揣度出数据类型,即“类型揣度”
* 1、添加类型Comparator<Integer> com2 = (Integer x,Integer y) -> Integer.compare(x,
* y); 2、不写类型Comparator<Integer> com2 = (x,y) -> Integer.compare(x, y);
*
*
* 上联:摆布遇一括号省, 下联:左侧揣度类型省, 横批:能省则省
*
* 二 、 Lambda表达式需要“函数式接口”的撑持
* 函数式接口:接口中只有一个抽象方式的接口,称为函数式接口。可以利用注解 @FunctionalInterface润色
*
* @FunctionalInterface:可以查抄是否是函数式接口
*
* @author Administrator
*
*/
public class TestLambda2 {
@Test
public void test1() {
int sum = 9;// jdk1.7 以前必需写final jdk1.8之后可以省略
Runnable r1 = new Runnable() {
public void run() {
System.out.println("Hello world!" + sum);
}
};
r1.run();
System.out.println("-----------------------------------");
Runnable r2 = () -> System.out.println("hello lambda");
r2.run();
}
@Test
public void test2() {
Consumer<String> com = (x) -> System.out.println(x);
com.accept("我爱进修java!");
Consumer<String> con = x -> System.out.println(x);
con.accept("我爱进修java!");
}
@Test
public void test3() {
Comparator<Integer> com = (x, y) -> {
System.out.println("函数式接口, 成果测试!");
return Integer.compare(x, y);
};
com.compare(7, 8);
Comparator<Integer> com2 = (Integer x, Integer y) -> Integer.compare(x, y);
com2.compare(7, 8);
Comparator<Integer> com3 = (x, y) -> Integer.compare(x, y);
com3.compare(7, 8);
}
// 类型揣度演示,jdk1.7以前就有
@Test
public void test4() {
/*
* String[] sts ; sts = {"ssss","bbbbb"};
*/
String[] sts = { "ssss", "bbbbb" };
List<String> list = new ArrayList<>();
// jdk1.8 之后可以这样写
show(new HashMap<>());
}
public void show(Map<String, Object> map) {
}
// 需求对一个数进交运算
@Test
public void test5() {
Integer num = operation(5, x -> x * x);
System.out.println("5的平方:" + num);
}
public Integer operation(Integer num, MyFun fun) {
return fun.getValue(num);
}
}
Lambda表达式操练:
package com.sgg.lambda3;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import com.sgg.lambda1.Employee;
public class TestLambda3 {
List<Employee> employees = Arrays.asList(new Employee("张三", 12, 1200.99), new Employee("小明", 15, 4500.99),
new Employee("小丽", 16, 5500.99), new Employee("王二", 32, 1100.99), new Employee("二虎", 22, 9825.99),
new Employee("李静", 18, 4502.99), new Employee("小三", 17, 1469.99));
// 操练1、挪用Collections.sort方式,经由过程定制排序比力Employee(先按春秋大小春秋不异按照姓名比力)
@Test
public void test1() {
Collections.sort(employees, (e1, e2) -> {
if (e1.getAge() == e2.getAge()) {
// return e1.getName().compareTo(e2.getName());
// 逆标的目的排序
return -e1.getName().compareTo(e2.getName());
} else {
// return Integer.compare(e1.getAge(),e2.getAge());
// 逆标的目的排序
return -Integer.compare(e1.getAge(), e2.getAge());
}
});
for (Employee emp : employees) {
System.out.println(emp);
}
}
// 操练2、
// 2.1 声明函数式接口,接口中声明抽象方式,public String getValue(String str);
// 2.2 声明类TestLambda3,类中挪用方式利用接口作为参数,将一个字符串转为大写,并作为方式的返回值
// 2.3 将一个字符串的第下标位置2到4之间的字符串截取
@Test
public void test2() {
String trimStr = strHandler("\t\t\t我爱进修java", str -> str.trim());
System.out.println(trimStr);
String trimStr2 = strHandler("aaaaaaaaa", str -> str.toUpperCase());
System.out.println(trimStr2);
String trimStr3 = strHandler("我爱进修java", str -> str.substring(2, 4));
System.out.println(trimStr3);
}
public String strHandler(String str, MyFunction mf) {
return mf.getValue(str);
}
// 操练3
// 3.1声明一个带两个泛型的函数式接口,泛型类型<T,R>,T为参数,R为返回值
// 3.2 接口中声明对应的抽象方式
// 3.3 在TestLambda3类中声明方式,利用接口作为参数,计较两个long型参数的和。
// 3.4计较两个long型参数的乘积
@Test
public void test3() {
long count = op(55, 20, (l1, l2) -> l1 + l2);
System.out.println(count);
long count2 = op(55, 20, (l1, l2) -> l1 * l2);
System.out.println(count2);
}
public long op(long l1, long l2, MyFunctionLong<Long, Long> ml) {
return ml.longCount(l1, l2);
}
}
内置函数式接口
package com.sgg.lambda4;
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;
import org.junit.Test;
/**
* jdk1.8 内置的四大焦点函数式接口
*
* Consumer<T>:消费型接口 void accept(T t);
*
* Supplier<T> :供给型接口 T get();
*
* Function<T, R> :函数型接口 R apply(T t);
*
* Predicate<T> : 断言型接口 boolean test(T t);
*
*
* @author Administrator
*
*/
public class TestLambda4 {
// Consumer<T>:消费型接口
@Test
public void test1() {
happy(600, x -> System.out.println("小明喜好大保健每次消费:" + x));
}
public void happy(double money, Consumer<Double> con) {
con.accept(money);
}
// Supplier<T> :供给型接口
// 需求:发生必然的整数并放入调集中
@Test
public void test2() {
List<Integer> list = getNumList(10, () -> (int) (Math.random() * 100));
for (Integer integer : list) {
System.out.println(integer);
}
}
public List<Integer> getNumList(int num, Supplier<Integer> sup) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < num; i++) {
Integer n = sup.get();
list.add(n);
}
return list;
}
// Function<T, R> :函数型接口
// 用于字符串处置
@Test
public void test3() {
String str = strHandler("\t\t\t\t我爱java", x -> x.trim());
System.out.println(str);
String trimStr2 = strHandler("aaaaaaaaa", x -> x.toUpperCase());
System.out.println(trimStr2);
String trimStr3 = strHandler("我爱进修java", x -> x.substring(2, 4));
System.out.println(trimStr3);
}
public String strHandler(String str, Function<String, String> ft) {
return ft.apply(str);
}
// Predicate<T> : 断言型接口
// 需求:将知足前提的字符串放入调集中去
@Test
public void test4() {
List<String> lists = Arrays.asList("sdsad", "我爱java", "我爱故国", "我爱人平易近");
List<String> listStr = filterStr(lists, x -> x.length() > 3);
for (String string : listStr) {
System.out.println(string);
}
}
public List<String> filterStr(List<String> listStr, Predicate<String> pre) {
List<String> lists = new ArrayList<>();
for (String str : listStr) {
if (pre.test(str)) {
lists.add(str);
}
}
return lists;
}
}
方式引用
package com.sgg.lambda5;
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.Test;
import com.sgg.lambda1.Employee;
/**
* 一 、方式引用:若Lambda体中内容有方式已经实现了,我们可以利用“方式引用” (可以理解为方式引用是Lambda表达式的另一种表示形式)
*
* 本家儿要有三种语法格局:
*
* 对象::实例方式名
*
* 类::静态方式名
*
* 类::实例方式名
*
* 注重: Lambda体中挪用方式的参数列表与返回值类型,要与函数式接口中抽象方式的函数列表和返回值类型一致!
* 若Lambda参数列表中的第一参数是实例方式的挪用者,第二参数是实例方式的参数时,可以利用ClassName::method
*
* 二 、机关器引用
*
* 格局: ClassName::new
*
* 注重:需要挪用的机关器的参数列表要与函数式接口中抽象方式的参数列表连结一致!
*
* 三 、数组引用
*
* Type::new;
*
* @author Administrator
*
*/
public class TestMethodRef {
// 对象::实例方式名
@Test
public void test1() {
// 第一种
Consumer<String> con2 = (x) -> System.out.println(x);
// 第二种
PrintStream ps1 = System.out;
Consumer<String> con1 = (x) -> ps1.println(x);
// 第三种
PrintStream ps = System.out;
Consumer<String> con3 = ps::println;
con3.accept("我爱宿世界!");
}
@Test
public void test2() {
Employee emp = new Employee();
Supplier<String> su = () -> emp.getName();
String st = su.get();
System.out.println(st);
Employee emp2 = new Employee();
Supplier<Integer> su2 = () -> emp2.getAge();
Integer num = su2.get();
System.out.println(num);
}
// 类::静态方式名
@Test
public void test3() {
Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
Comparator<Integer> com2 = Integer::compare;
}
// 类::实例方式名
@Test
public void test4() {
BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
BiPredicate<String, String> bp2 = String::equals;
}
// 类::机关器引用
@Test
public void test5() {
Supplier<Employee> su1 = () -> new Employee();
Supplier<Employee> su2 = Employee::new;
Employee em = su2.get();
System.out.println(em);
}
@Test
public void test6() {
Function<String, Employee> fun = (x) -> new Employee(x);
Employee em = fun.apply("小丽");
System.out.println(em);
}
// 数组引用
@Test
public void test7() {
Function<Integer, String[]> fun1 = (x) -> new String[x];
String[] sts1 = fun1.apply(10);
System.out.println(sts1.length);
Function<Integer, String[]> fun2 = String[]::new;
String[] sts2 = fun2.apply(20);
System.out.println(sts2.length);
}
}
源码地址:
链接: https://pan.baidu.com/s/1DpGycBWEJ43kXpuOgkzDQQ
提取码: umxt
0 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!