03 函数式接口
1 函数式接口
使用 @FunctionalInterface
注解将接口标注为函数式接口(当然,如果该接口仅有一个方法。那么,省略 @FunctionalInterface
注解同样可以)。然后,将方法引用或 Lambda
表达式赋值给函数式接口(类型需要匹配),Java
会自动适配赋值到目标接口。
package com.hcong.functional;/* @Classname FunctionalAnnotation* @Date 2023/4/12 13:41* @Created by HCong*/
@FunctionalInterface
interface Functional {String goodbye(String arg);
}interface FunctionalNoAnn {String goodbye(String arg);
}public class FunctionalAnnotation {public String goodbye(String arg) {return "Goodbye, " + arg;}public static void main(String[] args) {FunctionalAnnotation fa = new FunctionalAnnotation();Functional f = fa::goodbye;FunctionalNoAnn fna = fa::goodbye;Functional f1 = a -> "Goodbye, " + a;FunctionalNoAnn fna1 = a -> "Goodbye, " + a;}
}
java.util.function
包旨在创建一组完整的目标接口,使得我们一般情况下不需再定义自己的接口。例如:
@FunctionalInterface
public interface Function<T, R> {/* Applies this function to the given argument. @param t the function argument* @return the function result*/R apply(T t);
}
@FunctionalInterface
public interface IntFunction<R> {/* Applies this function to the given argument. @param value the function argument* @return the function result*/R apply(int value);
}
@FunctionalInterface
public interface ToIntFunction<T> {/* Applies this function to the given argument. @param value the function argument* @return the function result*/int applyAsInt(T value);
}
@FunctionalInterface
public interface IntToLongFunction {/* Applies this function to the given argument. @param value the function argument* @return the function result*/long applyAsLong(int value);
}
@FunctionalInterface
public interface Supplier<T> {/* Gets a result. @return a result*/T get();
}
下面是一些例子:
package com.hcong.functional;import java.util.function.*;/* @Classname FunctionVariants* @Date 2023/4/12 13:57* @Created by HCong*/
class Foo {
}class Bar {Foo f;Bar(Foo f) {this.f = f;}
}class IBaz {int i;IBaz(int i) {this.i = i;}
}class LBaz {long l;LBaz(long l) {this.l = l;}
}class DBaz {double d;DBaz(double d) {this.d = d;}
}public class FunctionVariants {static Function<Foo, Bar> f1 = f -> new Bar(f);static IntFunction<IBaz> f2 = i -> new IBaz(i);static LongFunction<LBaz> f3 = l -> new LBaz(l);static DoubleFunction<DBaz> f4 = d -> new DBaz(d);static ToIntFunction<IBaz> f5 = ib -> ib.i;static ToLongFunction<LBaz> f6 = lb -> lb.l;static ToDoubleFunction<DBaz> f7 = db -> db.d;static IntToLongFunction f8 = i -> i;static IntToDoubleFunction f9 = i -> i;static LongToIntFunction f10 = l -> (int) l;static LongToDoubleFunction f11 = l -> l;static DoubleToIntFunction f12 = d -> (int) d;static DoubleToLongFunction f13 = d -> (long) d;public static void main(String[] args) {Bar b = f1.apply(new Foo());IBaz ib = f2.apply(11);LBaz lb = f3.apply(11);DBaz db = f4.apply(11);int i = f5.applyAsInt(ib);long l = f6.applyAsLong(lb);double d = f7.applyAsDouble(db);l = f8.applyAsLong(12);d = f9.applyAsDouble(12);i = f10.applyAsInt(12);d = f11.applyAsDouble(12);i = f12.applyAsInt(13.0);l = f13.applyAsLong(13.0);}
}
package com.hcong.functional;import java.util.Comparator;
import java.util.function.*;/* @Classname ClassFunctionals* @Date 2023/4/12 14:15* @Created by HCong*/
class AA {
}class BB {
}class CC {
}public class ClassFunctionals {static AA f1() {return new AA();}static int f2(AA aa1, AA aa2) {return 1;}static void f3(AA aa) {}static void f4(AA aa, BB bb) {}static CC f5(AA aa) {return new CC();}static CC f6(AA aa, BB bb) {return new CC();}static boolean f7(AA aa) {return true;}static boolean f8(AA aa, BB bb) {return true;}static AA f9(AA aa) {return new AA();}static AA f10(AA aa1, AA aa2) {return new AA();}public static void main(String[] args) {Supplier<AA> s = ClassFunctionals::f1;s.get();Comparator<AA> c = ClassFunctionals::f2;c.compare(new AA(), new AA());Consumer<AA> cons = ClassFunctionals::f3;cons.accept(new AA());BiConsumer<AA, BB> bicons = ClassFunctionals::f4;bicons.accept(new AA(), new BB());Function<AA, CC> f = ClassFunctionals::f5;CC cc = f.apply(new AA());BiFunction<AA, BB, CC> bif = ClassFunctionals::f6;cc = bif.apply(new AA(), new BB());Predicate<AA> p = ClassFunctionals::f7;boolean result = p.test(new AA());BiPredicate<AA, BB> bip = ClassFunctionals::f8;result = bip.test(new AA(), new BB());UnaryOperator<AA> uo = ClassFunctionals::f9;AA aa = uo.apply(new AA());BinaryOperator<AA> bo = ClassFunctionals::f10;aa = bo.apply(new AA(), new AA());}
}
一旦将方法引用赋值给函数接口,我们就可以调用与该接口关联的函数方法。在此示例中为 get()
、compare()
、accept()
、apply()
和 test()
。
2 多参数函数式接口
如果需要三参数函数的接口需要自行创建!
package com.hcong.functional;/* @Classname TriFunction* @Date 2023/4/12 14:49* @Created by HCong*/
@FunctionalInterface
public interface TriFunction<T, U, V, R> {R apply(T t, U u, V v);
}class TriFunctionTest {static int f(int i, long l, double d) {return (int) (i + l + d);}public static void main(String[] args) {TriFunction<Integer, Long, Double, Integer> tf = TriFunctionTest::f;System.out.println(tf.apply(1, 2l, 3.0));tf = (i, l, d) -> (int) (i * l * d);System.out.println(tf.apply(1, 2l, 3.0));}
}
6
6