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));
}
}