前言
函數式接口是java 8之後的新特性,什麼是函數式接口呢?
函數式接口,就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的接口。
函數式接口在java中其實有很多,例如Runnable接口,在接口上的註解@FunctionalInterface
就是用來聲明這是一個函數式接口。
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
組成部分
函數式接口有很多,我很難說完,例如下面是jdk官方文檔給出的各種函數時接口。
這裏給大家介紹這四個:函數型接口、斷定型接口、消費型接口、供給型接口。
其實通過名字就可以大致知道這四個各自的作用與區別。
1.函數型接口:Function
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
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;
}
}
上面是函數型接口Funtion的源碼,只有一個抽象方法- apply()
,該方法有一個輸入一個輸出。剩下的是一些默認方法。
簡單使用Funtion接口
//函數型接口,一個輸入一個輸出
Function<String, String> function = new Function<String, String>() {
@Override
public String apply(String s) {
return s+",世界";
}
};
System.out.println(function.apply("你好"));
在上面的代碼中,我們聲明一個函數型接口,並且指定輸入和輸出的結果都是String類型。 然後傳參一個,它也會像函數那樣根據我們設定的返回值類型來返回結果。
最終返回結果:
你好,世界
2.斷定式接口:Predicate
@FunctionalInterface
public interface Predicate<T> {
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);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
上面是斷定型接口的源碼,我們給它一個輸出,它會給我們一個固定爲boolean類型的返回值,這也印證了“斷定”這樣一個概念。
//斷定型接口,有一個參數,返回值是固定的,即boolean類型
Predicate predicate = new Predicate<String>() {
@Override
public boolean test(String s) {
if(s.equals("你好"))
{
return true;
}
return false;
}
};
System.out.println(predicate.test("你好"));
上面的代碼中,我們書寫邏輯,如果傳入的字符串是“你好”,那麼就返回true。
最終返回結果如下:
true
3.消費型接口:Consumer
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
上面是消費型接口:Consumer
的源碼,只有一個輸入,而且可以看到,輸出類型是void,這也印證了它只管“消費”,不管返回這樣一個概念。
//消費型接口,一個輸入,沒有輸出
Consumer consumer = new Consumer<String>() {
@Override
public void accept(String o) {
System.out.println(o+":已被消費");
}
};
consumer.accept("你好世界");
最終輸出結果:
你好世界:已被消費
4.供給型接口:Supplier
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
上面是供給型接口Supplier
的源碼,只有一個返回值,沒有輸入,參數也是我們用來指定返回值類型的。 與前面消費型接口相比,是不是很有對比性,這個接口只管供給,而前面的消費型接口只管消費。
//供給型接口,沒有輸入,只有輸出,可以指定輸出的類型
Supplier supplier = new Supplier<String>() {
@Override
public String get() {
return "供給消息:你好世界";
}
};
System.out.println(supplier.get());
最終輸出結果
供給消息:你好世界