• Java8新特性--函数式编程


    在jdk8中什么是函数式接口: 
    1、被@FunctionalInterface注解修饰的。 
    2、接口里边只有一个非default的方法。 
    满足以上2个条件的即为函数式接口,ps:即使一个接口没有被@FunctionalInterface修饰,但是满足2,那么这样的接口也会是函数式接口。 
    Supplier 
    概要:不接受参数,返回一个值。 
    jdk源码:

     */
    @FunctionalInterface
    public interface Supplier<T> {
    
        /**
         * Gets a result.
         *
         * @return a result
         */
        T get();
    }

    即:Supplier不接受参数,返回一个值。 

    example:

    public class SupplierTest {
        public static void main(String[] args) {
            Supplier<Student> supplier = Student::new;//这里使用了方法引用(后续解释)生成了一个对象。
            System.out.println(supplier.get().getName());
        }
    }

    Function 
    概要:接受一个参数返回一个值 
    jdk源码:

    //类型T入参,类型R是返回值的类型
    @FunctionalInterface
    public interface Function<T, R> {
    
        /**
            接受一个参数,返回一个结果
         */
        R apply(T t);
    
        /**
         * 默认方法是讲的课8新加入的一种类型,入参before是一个Function(接受参数V类型,输出T类型),从实现来看其首先调用before的行为得到输出T,
         * 随后T作为当前Function的入参,最后当前Function输入R类型。即:compose函数传入的函数首先被调用,得到的结果作为当前Function的入参使用
         */
        default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
            Objects.requireNonNull(before);
            return (V v) -> apply(before.apply(v));
        }
    
        /**
         * andThen是和compose相反的操作,当前Function首先被调用,得到的结果作为参数after的入参,调用after。
         */
        default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
            Objects.requireNonNull(after);
            return (T t) -> after.apply(apply(t));
        }
    
        /**
         * 对接受的元素,不做处理
         */
        static <T> Function<T, T> identity() {
            return t -> t;
        }
    }

    BiFunction 
    概要:接受2个参数,返回一个值。 
    jdk源码:

    //T和U类型是参数,R类型是返回值。
    @FunctionalInterface
    public interface BiFunction<T, U, R> {
    
        /**
         * BiFunction的主方法,接受2个参数,返回一个结果
         */
        R apply(T t, U u);
    
        /**
         * 先执行当前BiFunction的行为,得到结果R类型,R类型最后作为Function的实例after的入参(泛型“? super R”即“?”是R类型或者是R类型的
         * 父级)返回V类型的结果。PS:考虑为什么andThen的入参是一个Function,而不是一个BiFunction?
         */
        default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
            Objects.requireNonNull(after);
            return (T t, U u) -> after.apply(apply(t, u));
        }
    }

    example:

    /**
     * Created by CeaserWang on 2017/1/8.
     */
    public class FunctionATest {
    
        public static void main(String[] args) {
            FunctionATest functionTestA = new FunctionATest();
           // functionTestA.testfunction1();
            System.out.println(functionTestA.computeA(3,value -> value = value * 3,value -> value+1));
    
            System.out.println(functionTestA.computeB(3,value -> value = value * 3,value -> value+1));
    
            System.out.println(functionTestA.computeC(3,4,(value1,value2) -> {return value1+value2;},value -> value*value));
        }
    
        public void testfunction1(){
            List<String> list = Arrays.asList("zhangsan","lisi","wangwu");
             Collections.sort(list,(o1,o2) -> {return o1.compareTo(o2); });
            Collections.sort(list,(o1,o2) ->  o1.compareTo(o2));
    
            list.forEach((item) -> System.out.println(item));
             list.forEach(String::toUpperCase);
             list.stream().map(String::toUpperCase).forEach(item -> System.out.println(item));
    
    
        }
    
        public int  computeA(int a, Function<Integer,Integer> function,Function<Integer,Integer> befor ){
            return  function.compose(befor).apply(a);
        }
    
        public int  computeB(int a, Function<Integer,Integer> function,Function<Integer,Integer> after ){
            return  function.andThen(after).apply(a);
        }
    
        public int  computeC(int a,int b, BiFunction<Integer, Integer,Integer> bifunction, Function<Integer,Integer> function ){
            return  bifunction.andThen(function).apply(a,b);
        }
    
    }

    BinaryOperator 
    概要:继承了BiFunction新加了2个求最大值和最小值的方法。 
    jdk源码:

    //继承了BiFunction,入参和返回值都是同一种类型T,因为2中相同类型的元素做大小比较,返回的是其中一个,即还是原来入参的类型。
    @FunctionalInterface
    public interface BinaryOperator<T> extends BiFunction<T,T,T> {
        /**
         * 根据比较器comparator求最小值
         */
        public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
            Objects.requireNonNull(comparator);
            return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
        }
    
        /**
         * 根据比较器comparator求最大值
         */
        public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
            Objects.requireNonNull(comparator);
            return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
        }
    }

    example:

    /**
     * Created by Administrator on 2017/1/8.
     */
    public class BinaryOperatorTest {
    
        public static void main(String[] args) {
            BinaryOperatorTest  BinaryOperatorTest = new BinaryOperatorTest();
            Integer rnum =   BinaryOperatorTest.compute(2,3,(num1,num2) -> {return num1 * num2;},value -> 2*value);
            System.out.println(rnum);
            System.out.println("-------------------------------------");
            Integer rnum2 =   BinaryOperatorTest.compute(2,3,(num1,num2) -> {return num1 * num2;});
            System.out.println(rnum2);
            System.out.println("-------------------------------------");
            Integer rnum3 =   BinaryOperatorTest.computeA(2,3,(num1,num2) ->   num1.compareTo(num2));
            System.out.println(rnum3);
        }
    
        public Integer compute(Integer a, Integer b, BinaryOperator<Integer> binaryoperator, Function<Integer,Integer> function) {
            return binaryoperator.andThen(function).apply(a,b);
        }
    
    
        public Integer compute(Integer a, Integer b, BinaryOperator<Integer> binaryoperator) {
            return binaryoperator.apply(a,b);
        }
    
    
        public Integer computeA(Integer a, Integer b, Comparator<Integer> comparator){
            return BinaryOperator.minBy(comparator).apply(a,b);
        }
    }

    Predicate 
    概要:接受一个参数返回boolean类型,常用语filter过滤条件使用。 
    jdk源码:

    @FunctionalInterface
    public interface Predicate<T> {
    
        /**
         * 接受一个参数返回一个boolean值
         */
        boolean test(T t);
    
        /**
         *与操作,支持短路与
         */
        default Predicate<T> and(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) && other.test(t);
        }
    
        /**
         * 取反操作
         */
        default Predicate<T> negate() {
            return (t) -> !test(t);
        }
    
        /**
         * 或操作,支持短路或
         */
        default Predicate<T> or(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) || other.test(t);
        }
    
        /**
         * 比较2个对象是否相同
         */
        static <T> Predicate<T> isEqual(Object targetRef) {
            return (null == targetRef)
                    ? Objects::isNull
                    : object -> targetRef.equals(object);
        }
    }

    example:

    /**
     * Created by CeaserWang on 2017/1/8.
     */
    public class PredicateTest {
        public static void main(String[] args) {
            Predicate<String> mypredicate = value -> value.length()>5;
            System.out.println(mypredicate.test("hello55s"));
    
            List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7,8,9);
            PredicateTest predicatetest = new PredicateTest();
            predicatetest.condationA(nums,value -> value>5);
            System.out.println("
    ---------------------------");
            predicatetest.condationA(nums,value -> value % 2 ==0);
            System.out.println("
    ---------------------------");
    
            System.out.println(predicatetest.condationEqual("test").test("test"));
        }
    
        public void condationA(List<Integer> list, Predicate<Integer> predate){
            for(Integer item : list){
                if(predate.test(item)){
                    System.out.print(item);
                }
            }
        }
    
        public Predicate<String> condationEqual(Object obj){
            return Predicate.isEqual(obj) ;
        }
    
    }

    Optional 
    概要:jdk8为了解决NPE问题提供的解决方案。 
    在jdk7中业务中很多代码都是这样:

    if(null!=XXX){
        doSomeThing();
    }

    开发人员需要警惕NPE问题,给开发带来了一些不便,现在我们不想用这三行固定的语句,为此jdk8有了Optional。 
    Optional内部维护了一个value的成员变量,为此Optional提供了诸多针对于此成员变量的方法。 
    Optional中的其中一个方法:

        //空对象
        private static final Optional<?> EMPTY = new Optional<>();
    
        //Optional维护的值
         private final T value; 
        //是否是空值
        public boolean isPresent() {
            return value != null;
        }
        //如果不是空值,那么执行针对于value的行为。
            public void ifPresent(Consumer<? super T> consumer) {
            if (value != null)
                consumer.accept(value);
        }
        //构造一个值为value的Optional对象,value不能为空,否则报错。
        public static <T> Optional<T> of(T value) {
            return new Optional<>(value);
        }
        //返回一个空值
        public static<T> Optional<T> empty() {
            @SuppressWarnings("unchecked")
            Optional<T> t = (Optional<T>) EMPTY;
            return t;
        }
        //创建一个允许空值的Optional对象
           public static <T> Optional<T> ofNullable(T value) {
            return value == null ? empty() : of(value);
        }

    example:

    /**
     * Created by CeaserWang on 2017/1/8.
     * optional 不要作为成员变量或者参数,optional只是为了应对null异常而来的
     */
    public class OptionalTest {
        public static void main(String[] args) {
            OptionalTest OptionalTest = new OptionalTest();
            OptionalTest.optionalA();
            OptionalTest.optionalB();
        }
    
    
        public void optionalA(){
            //Optional optional = Optional.of("hello");
            Optional optional = Optional.ofNullable(null);//创建一个空的对象
            optional.ifPresent(item -> System.out.println(item));//如果为空此行代码不会报错。
    
            System.out.println(optional.orElse("world"));//如果为空输出word
            System.out.println(optional.orElseGet(() -> "opop"));//如果为空,取Supplier提供的值
        }
    
    
        public void optionalB(){
            Company company = new Company();
            Employee e1 = new Employee();
            Employee e2 = new Employee();
            company.setEmployyee(Arrays.asList(e1,e2));
    
            Optional<Company> optional = Optional.ofNullable(company);
            System.out.println(optional.map(icompany -> icompany.getEmployyee()).orElse(Collections.emptyList()));
    
        }
    }

    函数式编程和以往的面向对象的方式有一定的区别,函数式编程方法的参数可以传递行为,这些行为包括但不限于以上介绍的这些,jdk8提供的函数式编程的辅助类在java.util.function包下边: 
    这里写图片描述

    这些针对于函数式编程的辅助类,对以后的收集器,流是基础,后续的jdk新加的框架都是使用这些基类展开的。

  • 相关阅读:
    Leetcode 433.最小基因变化
    穿越牛熊的“巴菲特”投资系统(发布于05-27 11:02)
    巴菲特的“安全边际”(发布于2019-6-16 10:39)
    安全边际:成功的基石(附选股)(选股策略系列五完结篇)(发布于06-14 11:11)
    分红与成长性:投资回报的体现(选股策略系列四)(发布于06-13 13:35)
    合理的资本结构:企业的生命线(选股策略系列2)(发布于06-11 12:44)
    稳定的每股利润:价值的基础(选股策略系列三)(发布于06-12 09:57)
    股票与债券的对比投资(发布于06-09 10:13)
    二类股值得投资吗?(选股策略系列一)(发布于06-10 15:51)
    透视伯克希尔投资组合---看巴菲特与格雷厄姆(发布于06-07 09:43)
  • 原文地址:https://www.cnblogs.com/kexianting/p/8692790.html
Copyright © 2020-2023  润新知