JAVA8 中的高阶函数

A Few Hidden Treasures in Java 8 on YouTube
是一个很有意思的视频。

函数式编程有一个很大的特点就是高阶函数。在很多”函数式“ 语言中,“函数”都是”第一公民“,就是说,函数可以像整数,浮点数,字符串等等普通值一样,可以作为函数的参数,也可以作为成员变量,函数的返回值。

在 JAVA 中,函数当然不是第一公民,函数是只有一个虚成员函数的接口。

如果一个函数的的参数是函数,或者返回值是函数,那么这个函数就是高阶函数。

任何非静态成员函数都可以看成一个函数,第一个参数是 this

下面是一个例子

public class SortPersonTest {
    public static List<Person> createPeople() {
        return Arrays.asList(
                new Person("Sara", Person.Gender.FEMALE, 20),
                new Person("Sara", Person.Gender.FEMALE, 22),
                new Person("Bob", Person.Gender.MALE, 20),
                new Person("Paula", Person.Gender.FEMALE, 32),
                new Person("Paul", Person.Gender.MALE, 32),
                new Person("JACk", Person.Gender.MALE, 2),
                new Person("JACK", Person.Gender.MALE, 72),
                new Person("Jill", Person.Gender.FEMALE, 12));
    }

    public static void main(String[] args) {

        createPeople().stream().sorted(
                Comparator.comparing(Person::getGender)
                        .reversed()
                        .thenComparing(Person::getAge)
                        .thenComparing(Person::getName))
                .forEach(System.out::println);
    }
}

程序输出

Person(name=Jill, gender=FEMALE, age=12)
Person(name=Sara, gender=FEMALE, age=20)
Person(name=Sara, gender=FEMALE, age=22)
Person(name=Paula, gender=FEMALE, age=32)
Person(name=JACk, gender=MALE, age=2)
Person(name=Bob, gender=MALE, age=20)
Person(name=Paul, gender=MALE, age=32)
Person(name=JACK, gender=MALE, age=72)

sorted 是一个高阶函数,第一个参数是 Stream this 。第二个参数是一个 Comparator 接口,这个接口只有一个虚函数,所以可以认为把一个函数作为参数。

Comparator::comparing 也是一个高阶函数,第一个参数是一个函数(Function),返回值也是一个函数(Comparator)。 类似实现可以是

    interface MyComparator<T> extends Comparator<T> {};
    public static <T, U extends Comparable<? super U>>
    MyComparator<T> comparing( Function<? super T, ? extends U> fKey) {
        return (t1, t2) -> fKey.apply(t1).compareTo(fKey.apply(t2));
    }

请忽略 Generic 的部分,这个不是本文的重点。

reversed 同样也是一个高阶函数,第一个函数是 Comparator (this) ,返回值还是一个函数 (Comparator),reversed 的实现可以类似下面

        default MyComparator<T> myReversed(){
            return (t1,t2) -> this.compare(t2,t1);
        }

thenComparing 的实现类似下面的代码

         default <U extends Comparable<? super U>> MyComparator<T> myThenComparing(Function<? super T, ? extends U> fKey) {
            return (t1, t2) -> {
                final int r1 = compare(t1, t2);
                return r1 == 0 ? myComparing(fKey).compare(t1,t2): r1;
            };
        }

完整代码

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;

public class SortPersonTest {
    public static List<Person> createPeople() {
        return Arrays.asList(
                new Person("Sara", Person.Gender.FEMALE, 20),
                new Person("Sara", Person.Gender.FEMALE, 22),
                new Person("Bob", Person.Gender.MALE, 20),
                new Person("Paula", Person.Gender.FEMALE, 32),
                new Person("Paul", Person.Gender.MALE, 32),
                new Person("JACk", Person.Gender.MALE, 2),
                new Person("JACK", Person.Gender.MALE, 72),
                new Person("Jill", Person.Gender.FEMALE, 12));
    }
    interface MyComparator<T> extends Comparator<T> {
        default MyComparator<T> myReversed(){
            return (t1,t2) -> this.compare(t2,t1);
        }
        default <U extends Comparable<? super U>> MyComparator<T> myThenComparing(Function<? super T, ? extends U> fKey) {
            return (t1, t2) -> {
                final int r1 = compare(t1, t2);
                return r1 == 0 ? myComparing(fKey).compare(t1,t2): r1;
            };
        }
    };

    public static <T, U extends Comparable<? super U>>
    MyComparator<T> myComparing(Function<? super T, ? extends U> fKey) {
        return (t1, t2) -> fKey.apply(t1).compareTo(fKey.apply(t2));
    }
    public static void main(String[] args) {

        createPeople().stream().sorted(
                myComparing(Person::getGender)
                        .myReversed()
                        .myThenComparing(Person::getAge)
                        .myThenComparing(Person::getName))
                .forEach(System.out::println);
    }
}
    原文作者:017830d97951
    原文地址: https://www.jianshu.com/p/c76d4f68d3dd
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞