• java8新特性——函数式接口,方法,构造器,数组引用


    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));
        }
    }
  • 相关阅读:
    a和b互换的2种方式
    spring cloud 方法调用 feign
    spring boot redis 五种类型使用实例
    springboot引入properties文件 yml文件
    Spark-Streaming结合Redis
    Spark-Streaming结合Mysql案例
    Springboot与scala编写第一个web程序
    Springboot工程Mybatis二级缓存配置
    小奇画画
    saf
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12178647.html
Copyright © 2020-2023  润新知