A Few Hidden Treasures in Java 8 on YouTube
是一個(gè)很有意思的視頻锡凝。
函數(shù)式編程有一個(gè)很大的特點(diǎn)就是高階函數(shù)误甚。在很多”函數(shù)式“ 語言中香伴,“函數(shù)”都是”第一公民“,就是說豆挽,函數(shù)可以像整數(shù)甲捏,浮點(diǎn)數(shù),字符串等等普通值一樣以政,可以作為函數(shù)的參數(shù)霸褒,也可以作為成員變量,函數(shù)的返回值盈蛮。
在 JAVA 中废菱,函數(shù)當(dāng)然不是第一公民,函數(shù)是只有一個(gè)虛成員函數(shù)的接口。
如果一個(gè)函數(shù)的的參數(shù)是函數(shù)殊轴,或者返回值是函數(shù)衰倦,那么這個(gè)函數(shù)就是高階函數(shù)。
任何非靜態(tài)成員函數(shù)都可以看成一個(gè)函數(shù)梳凛,第一個(gè)參數(shù)是 this
耿币。
下面是一個(gè)例子
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
是一個(gè)高階函數(shù),第一個(gè)參數(shù)是 Stream this
韧拒。第二個(gè)參數(shù)是一個(gè) Comparator
接口淹接,這個(gè)接口只有一個(gè)虛函數(shù),所以可以認(rèn)為把一個(gè)函數(shù)作為參數(shù)叛溢。
Comparator::comparing
也是一個(gè)高階函數(shù)塑悼,第一個(gè)參數(shù)是一個(gè)函數(shù)(Function),返回值也是一個(gè)函數(shù)(Comparator)楷掉。 類似實(shí)現(xiàn)可以是
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));
}
請(qǐng)忽略 Generic 的部分厢蒜,這個(gè)不是本文的重點(diǎn)。
reversed
同樣也是一個(gè)高階函數(shù)烹植,第一個(gè)函數(shù)是 Comparator (this) 斑鸦,返回值還是一個(gè)函數(shù) (Comparator),reversed
的實(shí)現(xiàn)可以類似下面
default MyComparator<T> myReversed(){
return (t1,t2) -> this.compare(t2,t1);
}
thenComparing
的實(shí)現(xiàn)類似下面的代碼
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);
}
}