学了尚硅谷老师java8视频之后,本人一点一滴的对代码做了如下总结。仅供学习。
1、lambda表达式过渡:(优化方式1-优化方式4,追层优化,简化代码开发,可读性增强)
package com.example.demo.java8_1_lambda表达式过渡;
import com.example.demo.domain.Employee;
import org.junit.Test;
import java.util.*;
import java.util.stream.Collectors;
/**
* 体验lambda表达式
*/
public class Test0 {
@Test
public void test1(){
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
TreeSet<Integer> ts = new TreeSet<>(comparator);
ts.add(1);
ts.add(3);
ts.add(2);
System.out.println(ts);
}
@Test
public void test2(){
Comparator<Integer> comparator = (o1,o2) -> Integer.compare(o1,o2);
TreeSet<Integer> ts = new TreeSet<>(comparator);
ts.add(1);
ts.add(3);
ts.add(2);
System.out.println(ts);
}
@Test
public void test3(){
Comparator<Integer> comparator = Integer::compareTo;
TreeSet<Integer> ts = new TreeSet<>(comparator);
ts.add(1);
ts.add(3);
ts.add(2);
System.out.println(ts);
}
/**
* =======================================================================
*/
List<Employee> employees = Arrays.asList(
new Employee("张三",18,9999.99),
new Employee("李四",38,5555.99),
new Employee("王五",50,6666.66),
new Employee("赵六",16,3333.33),
new Employee("田七",8,7777.77)
);
//需求1:获取当前公司员工中年龄大于35的员工信息
public List<Employee> filterEmployees(List<Employee> employees){
List<Employee> emps = new ArrayList<>();
for (Employee employee : employees) {
if(employee.getAge() > 35){
emps.add(employee);
}
}
return emps;
}
@Test
public void test4(){
System.out.println(filterEmployees(employees));
}
/**
* =======================================================================
*/
//需求2:获取当前公司员工中工资大于5000的员工信息
// 里边的方法跟需求1 差不多,再写一遍累赘,冗余代码
//早先优化用设计模式 ,现在不需要了
/**
* 优化方式1 ,策略设计模式
*/
public List<Employee> filterEmployee(List<Employee> employees,MyPredicate<Employee> myPredicate){
List<Employee> emps = new ArrayList<>();
for (Employee employee : employees) {
if(myPredicate.test(employee)){
emps.add(employee);
}
}
return emps;
}
@Test
public void test5(){
System.out.println(filterEmployee(employees,new FilterEmployeeByAge()));
System.out.println("-----------------------------");
System.out.println(filterEmployee(employees,new FilterEmployeeBySalary()));
System.out.println("-----------------------------");
}
//优化方式2: 每次都要实现MyPredicate接口,只写一点,多余。。。---匿名内部类优化
@Test
public void test6(){
List<Employee> employees = filterEmployee(this.employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getSalary() <= 5000;
}
});
System.out.println(employees);
}
//优化方式3 lambda表达式
@Test
public void test7(){
List<Employee> employees = filterEmployee(this.employees, (employee -> employee.getSalary() <= 5000));
System.out.println(employees);
}
//优化方式4 MyPredicate接口,以及一切继承类都不再需要 stream api优化
@Test
public void test8(){
List<Employee> collect = employees
.stream()
.filter((employee -> employee.getSalary() >= 5000))
.limit(2) //取前两个数据
.collect(Collectors.toList());
System.out.println(collect);
System.out.println("----------------");
//把集合中所有名字提取出来
List<String> collect1 = employees.stream().map(Employee::getName).collect(Collectors.toList());
System.out.println(collect1);
}
}
2、Lambda表达式基本语法
package com.example.demo.java8_2_lambda表达式;
import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* 一、Lambda表达式基本语法 (列表参数) -> lambda体
*
* 语法格式1:无参数,无返回值
* () -> System.out.println("hello lambda");
*
* 语法格式2: 有一个参数,并且无返回值
* (x) -> System.out.println(x);
*
* 语法格式3: 若只有一个参数,小括号可以省略不写
*
* 语法格式4: 两个以上的参数,有返回值,并且lambda体中有多条语句
* Comparator<Integer> com = (x,y) -> {
* System.out.println("函数式接口");
* return Integer.compare(x,y);
* };
*
* 语法格式5:若lambda体只有一条语句,return和大括号都可以省略不写
*
* 语法格式6:参数类型可以不写,jvm推断出参数类型
*
* 二、Lambda表达式需要函数式接口的支持
*
*/
public class TestLambda {
@Test
public void test1(){
//语法格式1: 无参,无返回值 demo
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("hello lambda");
}
};
r1.run();
System.out.println("=================================");
Runnable r2 = () -> System.out.println("hello lambda");
r2.run();
}
@Test
public void test2(){
//语法格式2:有一个参数,并且无返回值
Consumer<String> con = (x) -> System.out.println(x);
con.accept("我大中国威武");
}
@Test
public void test4(){
//语法格式4: 两个以上的参数,有返回值,并且lambda体中有多条语句
Comparator<Integer> com = (x,y) -> {
System.out.println("函数式接口");
return Integer.compare(x,y);
};
System.out.println(com.compare(3,2));
}
//需求:对一个数进行运算
@Test
public void test5(){
System.out.println(operation(10, x -> x* x));
}
public Integer operation(Integer num, Function<Integer,Integer> fun){
return fun.apply(num);
}
}
3、Lambda表达式基本语法练习
package com.example.demo.java8_2_lambda表达式;
import com.example.demo.domain.Employee;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class TestLambdaPractise {
List<Employee> employees = Arrays.asList(
new Employee("张三",18,9999.99),
new Employee("李四",38,5555.99),
new Employee("王五",50,6666.66),
new Employee("赵六",16,3333.33),
new Employee("田七",8,7777.77),
new Employee("阿八",8,7777.77)
);
//一、调用Collections.sort() 方法,通过定制排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递
@Test
public void test1(){
Collections.sort(employees,(e1,e2)-> {
if(e1.getAge() == e2.getAge()){
return -e1.getName().compareTo(e2.getName());
}else {
return Integer.compare(e1.getAge(),e2.getAge());
}
});
employees.forEach(System.out::println);
}
//二、1、声明函数式接口,接口中声明抽象方法, public String getValue(String str);
//二、2、声明类TestLambda,类中编写方法使用接口作为参数,将一个字符串转换为大写,并作为方法的返回值
@Test
public void test2(){
System.out.println(getStr("adsada",String::toUpperCase));
}
public String getStr(String str,MyInterface myInterface){
return myInterface.getValue(str);
}
//二、3、再讲一个字符串的第二个和第四个索引位置进行截取子串
@Test
public void test3(){
System.out.println(getStr("dasdsaddvcs",x -> x.substring(1,4)));
}
//三、1、声明一个带两个泛型的函数式接口,泛型类型为<T,R>,T为参数,R为返回值
//三、2、接口中声明对应抽象方法
//三、3、在TestLambda类中声明方法,使用接口作为参数,计算两个long参数的和
@Test
public void test4(){
System.out.println(getSalary(1000,2000,(x,y) -> x+y));
}
public double getSalary(double money1,double money2,MyInterface2<Double,Double> myInterface2){
return myInterface2.getTh(money1,money2);
}
//三、4、再计算两个long参数的乘积
@Test
public void test5(){
System.out.println(getSalary(100,300,(x,y) -> x*y));
}
}
4、四大内置核心函数式接口
package com.example.demo.java8_3_四大内置核心函数式接口;
import org.junit.Test;
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;
/**
* 内置的四大核心函数式接口
* 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 TestLambda {
//1、Consumer<T> :消费型接口
@Test
public void test1(){
happy(1000,m -> System.out.println("消费"+m));
}
public void happy(double money, Consumer<Double> con){
con.accept(money);
}
//2、Supplier<T> :供给型接口
//产生指定个数的整数,并放入集合中
@Test
public void test2(){
//随机产生10个整数放到集合中
System.out.println(getNumList(10,()-> (int)(Math.random()*100)));
}
public List<Integer> getNumList(int num , Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add(sup.get());
}
return list;
}
//Function<T,R> :函数型接口
//需求:用于处理字符串
@Test
public void test3(){
System.out.println(strHandler("dasd",String::toUpperCase));
}
public String strHandler(String str, Function<String,String> fun){
return fun.apply(str);
}
//Predicate<T> :断言型接口
//需求:将满足条件的字符串放入结合中,并返回
@Test
public void test4(){
List<String> list = Arrays.asList("hello","lambda","wwwww","ok");
System.out.println(filterStr(list, s -> s.length()> 3));
}
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;
}
}
5、方法引用与构造器引用
package com.example.demo.java8_4_方法引用与构造器引用;
import com.example.demo.domain.Employee;
import org.junit.Test;
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;
/**
* 方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”
* (可以理解为方法引用是Lambda表达式的另外一种表现形式)
*
* 语法格式:
* 1、对象::实例方法名
*
* 2、类::静态方法名
*
* 3、类::实例方法名
*
* 构造器引用:ClassName::new
*
* 数组引用:Type::new
*/
public class TestMethodRef {
@Test
public void test1(){
Consumer<String> con = x -> System.out.println(x);
//对象::实例方法名
PrintStream ps = System.out;
Consumer<String> con1 = ps::println;
con1.accept("dasdasd");
}
@Test
public void test2(){
//对象::实例方法名
Employee emp = new Employee();
Supplier<String> sup = () -> emp.getName();
System.out.println(sup.get());
System.out.println("----------------------");
Supplier<Integer> sup1 = emp::getAge;
System.out.println(sup1.get());
}
@Test
public void test3(){
//类::静态方法名
Comparator<Integer> con = (x, y) -> Integer.compare(x,y);
System.out.println(con.compare(3,4));
System.out.println("-----------------");
Comparator<Integer> con1 = Integer::compare;
System.out.println(con1.compare(1,5));
}
@Test
public void test4(){
//类::实例方法名
BiPredicate<String,String> bp1 = (x,y) -> x.equals(y);
System.out.println("-----------------");
BiPredicate<String,String> bp2 = String::equals;
System.out.println( bp2.test("x","x"));
}
@Test
public void test5(){
//构造器引用:ClassName::new
Supplier<Employee> sup1 = () -> new Employee();
Supplier<Employee> sup2 = Employee::new; //注意:一定调用的是无参构造,
}
@Test
public void test6(){
//数组引用:Type::new
Function<Integer,String[]> fun1 = x -> new String[x];
System.out.println(fun1.apply(10).length);
System.out.println("--------------------");
Function<Integer,String[]> fun2 = String[]::new;
System.out.println(fun2.apply(10).length);
}
}
6、练习再做
package com.example.demo.java8_4_练习再做;
import com.example.demo.domain.Employee;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
public class TestPractise {
List<Employee> employees = Arrays.asList(
new Employee("张三",18,9999.99),
new Employee("李四",38,5555.99),
new Employee("王五",50,6666.66),
new Employee("赵六",16,3333.33),
new Employee("田七",8,7777.77),
new Employee("阿八",8,7777.77)
);
//一、调用Collections.sort() 方法,通过定制排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递
@Test
public void test1(){
employees.sort((x,y) -> {
if(x.getAge() == y.getAge()){
return x.getName().compareTo(y.getName());
}else{
return Integer.compare(x.getAge(),y.getAge());
}
});
employees.forEach(System.out::println);
}
//二、1、声明函数式接口,接口中声明抽象方法, public String getValue(String str);
//二、2、声明类TestLambda,类中编写方法使用接口作为参数,将一个字符串转换为大写,并作为方法的返回值
@Test
public void test2(){
Function<String,String> fun = String::toUpperCase;
System.out.println(fun.apply("zhansgan"));
}
//二、3、再讲一个字符串的第二个和第四个索引位置进行截取子串
@Test
public void test3(){
Function<String,String> fun = x -> x.substring(1,4);
System.out.println(fun.apply("zhangsan"));
}
//三、1、声明一个带两个泛型的函数式接口,泛型类型为<T,R>,T为参数,R为返回值
//三、2、接口中声明对应抽象方法
//三、3、在TestLambda类中声明方法,使用接口作为参数,计算两个long参数的和
@Test
public void test4(){
BiFunction<Long,Long,Long> biFunction = (x,y) -> x+y;
System.out.println(biFunction.apply(111l,222l));
}
//三、4、再计算两个long参数的乘积
@Test
public void test5(){
BiFunction<Long,Long,Long> biFunction = (x,y) -> x*y ;
System.out.println(biFunction.apply(100l,900l));
}
}
7、stream api