java8知识点总结
学了尚硅谷老师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