所谓的函数式接口,实际上就是接口里面只能有一个抽象方法的接口。Comparator接口就是一个典型的函数式接口,它只有一个抽象方法compare。
甚至可以说:函数式接口是专门为lambda表达式准备的,lambda表达式是只实现接口中唯一的抽象方法的匿名实现类。
JDK中的函数式接口举例:
java.lang.Runnable,
java.util.Comparator,
java.util.concurrent.Callable
java.util.function包下的接口,如Consumer、Predicate、Supplier等
public interface Animal {
/**
* 接口中的抽象方法
*/
void call();
/**
* 接口中的默认方法
* @param food
*/
default void like(String food) {
System.out.println("我喜欢吃:" + food);
}
/**
* 接口中的静态方法
* @param food
*/
static void hite(String food) {
System.out.println("我不喜欢吃:" + food);
}
}
public class Dog implements Animal{
@Override
public void call() {
System.out.println("我是一只 little Dog");
}
}
public class InterfaceTest {
public static void main(String[] args) {
Dog dog = new Dog();
dog.call();
dog.like("骨头");
Animal.hite("稀饭");
}
}
我是一只 little Dog
我喜欢吃:骨头
我不喜欢吃:稀饭
default关键字,在java8之前接口是不能有方法的实现,所有方法全都是抽象方法,实现接口就必须实现接口里面的所有方法。这就导致一个问题:当一个接口有很多的实现类的时候,修改这个接口就变成了一个非常麻烦的事,需要修改这个接口的所有实现类。
这个问题困扰了java工程师许久,不过在java8中这个问题得到了解决,没错就是default方法:
描述:用来生产数据。
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
例:使用Supplier计算数组中最大的数
public class SupplierTest {
public static void main(String[] args) {
fun(() -> {
int[] number = {1, 2, 3, 4, 5};
Arrays.stream(number);
return number[number.length - 1]; // 这个return就是 supplier.get();
});
}
private static void fun(Supplier<Integer> supplier) {
Integer max = supplier.get();
System.out.println("Max: " + max);
}
}
描述:有参无返回值的接口,用来消费数据。使用的时候需要指定泛型来定义参数类型。
@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); };
}
}
例如:将输入的数据统一转换为小写输出。
public class ConsumerTest {
public static void main(String[] args) {
fun((msg) -> {
System.out.println(msg.toLowerCase());
});
}
public static void fun(Consumer<String> consumer) {
consumer.accept("Hello World");
}
}
默认andThen方法,如果一个方法的参数和返回值都是Consumer,那么就可以实现效果,消费一个数据的时候首先做一个操作,然后做一个操作,实现组合。
public class ConsumerTest {
public static void main(String[] args) {
fun2((msg1) -> {
System.out.println(msg1.toLowerCase());
}, (msg2) -> {
System.out.println(msg2.toUpperCase());
});
}
public static void fun2(Consumer<String> c1, Consumer<String> c2) {
// c1.accept("Hello World"); // 转小写
// c2.accept("Hello World"); // 转大写
c1.andThen(c2).accept("Hello World");
}
}
描述:有参数有返回值的接口。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;
}
}
例如:传进去一个字符串,返回一个Integer类型。
public class FunctionTest {
public static void main(String[] args) {
fun((msg) -> {
return Integer.parseInt(msg); // 方法体
});
}
public static void fun(Function<String, Integer> function) {
Integer integer = function.apply("727");
System.out.println(integer);
}
}
默认andThen方法,也是用来进行组合操作的。
public class FunctionTest {
public static void main(String[] args) {
fun2((msg1) -> {
return Integer.parseInt(msg1);
}, (msg2) -> {
return msg2 * 10;
});
}
public static void fun2(Function<String, Integer> f1, Function<Integer, Integer> f2) {
// Integer s1 = f1.apply("22");
// Integer s2 = f2.apply(s1);
Integer s2 = f1.andThen(f2).apply("22");
System.out.println(s2);
}
}
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
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);
}
}
例如:用于判断
public class PredicateTest {
public static void main(String[] args) {
fun(m -> {
return m.length() > 2;
}, "hello");
}
public static void fun(Predicate<String> predicate, String msg) {
boolean is = predicate.test(msg);
System.out.println(is);
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。