package functional; /* 定义:如果一个接口里面只声明了一个函数,就称为函数式接口 lambda表达式的本质:作为函数式接口的实例,必须依赖一类特别的对象类型——函数式接口 所以用匿名实现类表示的都可以用lambda表达式来写 Java.util.function 下也定义了Java8的函数式接口 函数式接口 内置抽象类 作用 1.Consumer<T>: void accept(T t) 消费型 2.Supplier<T>: T get() 返回一个对应的T对象 3.Function<T,R>: R apply(T t) 对T的对象做一些处理,返回另一个R对象 4.Predicate<T>: boolean test(T t) 测试T对象是否满足要求 @author zsben @create 2020-01-10 19:13 */ 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.Predicate; //函数式接口注解 @FunctionalInterface interface MyInterface{ void method1(); } public class FunctionalTest { //第一类:消费性函数式接口 Consumer<T> public void happyTime(double money, Consumer<Double> consumer){ consumer.accept(money); } @Test public void test1(){ //这种写法是实现了Consumer<Double>的匿名子类对象 happyTime(500, new Consumer<Double>() { @Override public void accept(Double aDouble) { System.out.println(aDouble); } }); System.out.println("************************************"); //通过lambda表达式实现函数式对象 happyTime(400,money -> System.out.println(money)); } //第二类:断言型函数式接口Predicate<T> //根据给定的规则,过滤集合中的字符串,此规则由Predicate的方法决定 public ArrayList<String> filterString(List<String >list, Predicate<String> pre){ ArrayList<String> filterList = new ArrayList<>(); for(String s:list){ if(pre.test(s)) filterList.add(s); } return filterList; } @Test public void test2(){ List<String> list = Arrays.asList("北京","南京","天津","东京","西京"); //把名字里带有京的留下来 List<String> filterStrs = filterString(list, new Predicate<String>() { @Override public boolean test(String s) { return s.contains("京"); } }); System.out.println(filterStrs); System.out.println("********************************************"); //这里其实就是用lambda把Predicate里的test(s)实现了 List<String> filterStrs1 = filterString(list, s -> s.contains("京")); System.out.println(filterStrs1); } }
package functional; /* 方法引用:顾名思义就是引用一个方法 1.使用情景:当要传递给lambda体的操作,已经有实现的方法了,可以使用方法引用 2.方法引用:本质上就是lambda表达式,而lambda作为函数式接口的实例, 所以方法引用,也是函数式接口的实例 3.使用格式: 类::静态方法名 类::非静态方法名 对象::非静态方法名 4.使用要求:接口中的抽象方法形参列表和返回值的类型 与 方法引用的方法的形参列表,返回值都相同 @author zsben @create 2020-01-10 19:58 */ 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; public class MethodreferencesTest { //情景一:对象::实例方法 //Consumer中的void accept(T t) //PrintStream 中的 void println(T t) @Test public void test1() { Consumer<String> con1 = str -> System.out.println(str); con1.accept("北京"); System.out.println("***************************"); //System.out其实是一个打印流对象,有println(String s)这个方法 PrintStream ps = System.out; Consumer<String> con2 = ps::println;//con2引用ps的方法println } //Supplier中的get() //Employee中的String getName() @Test public void test2(){ Employee emp = new Employee(1001,"Tom",23,5600); Supplier<String> sup1 = ()->emp.getName(); System.out.println(sup1.get()); System.out.println("**********************************"); Supplier<String> sup2 = emp::getName; System.out.println(sup2.get()); } //情景二:类::静态方法 //Comparator中的int compare(T t1,T t2) //Integer 中的int compare(T t1,T t2) @Test public void test3(){ Comparator<Integer> com1 = (t1, t2) -> Integer.compare(t1,t2); System.out.println(com1.compare(1,2)); System.out.println("******************************"); Comparator<Integer> com2 = Integer::compare; } //Function中的 R apply(T t) //Math 中的long round(Double d) @Test public void test4(){ Function<Double, Long> func1 = d -> Math.round(d); System.out.println("*****************************"); Function<Double, Long> func2 = Math::round;//这个函数的形参,返回值必须一致 } //情况三: 类::非静态方法 //这种情况需要从lambda表达式对应的形参中抽出一个参数来当成该类的实例对象,并通过这个类调用后面的方法 //Comparator中的int compare(T t1,T t2) //String中int t1.compareTo(t2) @Test public void test5(){ Comparator<String> com1 = (s1,s2)->s1.compareTo(s2); System.out.println(com1.compare("123", "321")); System.out.println("-********************************"); Comparator<String> com2 = String::compareTo; System.out.println(com2.compare("123", "321")); } //BiPredicate 中的boolean test(T t1,T t2) //String 中的boolean t1.equals(t2) @Test public void test6(){ BiPredicate<String, String> pre1 = (s1,s2)->s1.equals(s2); System.out.println(pre1.test("abd","asd")); System.out.println("*********************************"); BiPredicate<String, String> pre2 = String::equals; System.out.println(pre2.test("abd","asd")); } //Function 中的 R apply(T t) //Employee 中的 String getName(); @Test public void test7(){ Function<Employee,String> func1 = (emp)->emp.getName(); System.out.println(func1.apply(new Employee(1, "zsben", 23, 25000))); System.out.println("*********************************"); Function<Employee,String> func2 = Employee::getName; System.out.println(func2.apply(new Employee(1, "zsben", 23, 25000))); } }
package functional; /* 1.构造器引用 和方法引用类似,函数式接口的抽象方法的形参列表和构造器和形参列表一致 抽象方法的返回值类型即为构造器所属的类的类型 2.数组引用 把数组看成是一个特殊的类,则写法和构造器引用一致 @author zsben @create 2020-01-10 22:05 */ import org.junit.Test; import java.util.Arrays; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; public class ConstructorTest { //构造器引用 //Suppier中的T get() @Test public void test1(){ Supplier<Employee> sup1 = () -> new Employee(); System.out.println(sup1.get()); Supplier<Employee> sup2 = Employee::new; System.out.println(sup2.get()); } //Function中的R apply(T t) @Test public void test2(){ Function<Integer,Employee> func1 = id -> new Employee(id); System.out.println(func1.apply(1)); System.out.println("*********************************"); Function<Integer,Employee> func2 = Employee::new; System.out.println(func2.apply(1)); } //BiFunction中的R apply(T t,U u) @Test public void test3(){ BiFunction<Integer,String,Employee> func1 = (id,name)->new Employee(id,name); System.out.println(func1.apply(1,"zsben")); System.out.println("*********************************"); BiFunction<Integer,String,Employee> func2 = Employee::new; System.out.println(func1.apply(1,"zsben")); } //数组引用 //Function中的R apply(T t) @Test public void test4(){ Function<Integer,String[]> func1 = (length)->new String[length]; String[] arr1 = func1.apply(6); System.out.println(Arrays.toString(arr1)); System.out.println("*********************************"); Function<Integer,String[]> func2 = String[]::new; String[] arr2=func2.apply(1); System.out.println(Arrays.toString(arr1)); } }