持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
什么是函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口可以被隐式转换为 lambda 表达式。
Lambda 表达式和方法引用(实际上也可认为是Lambda表达式)上,
说到函数式接口那么这个注解 @FunctionalInterface是函数式借口所必须的。
我们定义一个函数式接口
@FunctionalInterface
interface GreetingService
{
void sayMessage(String message);
}
public static void main(String[] args) {
//1.8之前 使用的是匿内部类来处理
sayMessageTo(new GreetingService() {
@Override
public void sayMessage(String message) {
System.out.println("匿内部类 message = "+message);
}
});
//这是 Lambda 来实现的
sayMessageTo((me)->{
System.out.println("Lambda message = " + me);
});
}
public static void sayMessageTo(GreetingService greetingService){
greetingService.sayMessage("helle");
}
输出结果
匿内部类 message = helle
Lambda message = helle
下面我们看看JDK 为我们提供的函数式接口
JDK为我们提供的函数式接口一般是在 java.util.function 包下
下面我们列举几个常用的
1. Supplier 无入参但是有返回值
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
使用如下:
public static void main(String[] args) {
sayMessageTo(()->{
//当然这里可以做一些计算处理这里只是演示就直接返回 100了
return 100;
});
}
public static void sayMessageTo(Supplier<Integer> greetingService){
//get()抽象方法
Integer integer = greetingService.get();
System.out.println("integer = " + integer);
}
结果
integer = 100
2. Consumer 有入参无返回值 Consumer <T> 这里的T是指入参泛型
这里讲字符串转换成小写
public static void main(String[] args) {
sayMessageTo((msg)->{
String s = msg.toLowerCase(Locale.ROOT);
System.out.println("s = " + s);
});
}
public static void sayMessageTo(Consumer<String> consumer){
String str="Java is the first";
consumer.accept(str);
}
这里需要注意一个新特性 默认方法 andThen
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
使用如下
public static void main(String[] args) {
sayMessageTwo((msg)->{
//转小写
String s = msg.toLowerCase(Locale.ROOT);
System.out.println("msg1 = " + s);
},msg2->{
// 转大写
String s = msg2.toUpperCase();
System.out.println("msg2 = " + s);
});
}
public static void sayMessageTwo(Consumer<String> consumer,Consumer<String> consumer2){
String str="Java is the first";
consumer.accept(str);
consumer2.accept(str);
consumer.andThen(consumer2).accept(str);
}
msg1 = java is the first
msg2 = JAVA IS THE FIRST
3. 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);
/**
* Returns a composed function that first applies the {@code before}
* function to its input, and then applies this function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of input to the {@code before} function, and to the
* composed function
* @param before the function to apply before this function is applied
* @return a composed function that first applies the {@code before}
* function and then applies this function
* @throws NullPointerException if before is null
*
* @see #andThen(Function)
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@code after} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of output of the {@code after} function, and of the
* composed function
* @param after the function to apply after this function is applied
* @return a composed function that first applies this function and then
* applies the {@code after} function
* @throws NullPointerException if after is null
*
* @see #compose(Function)
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
}
使用:
public static void main(String[] args) {
sayMessageTwo((msg)->{
return Integer.parseInt(msg);
});
}
public static void sayMessageTwo(Function<String,Integer> f1){
Integer apply = f1.apply("100");
System.out.println("apply = " + apply);
}
apply = 100
默认方法 andThen
public static void main(String[] args) {
sayMessageTwo((msg)->{
return Integer.parseInt(msg);
},msg2 ->{
return msg2 *10;
});
}
public static void sayMessageTwo(Function<String,Integer> f1, Function<Integer,Integer> f2){
Integer apply = f1.andThen(f2).apply("100");
System.out.println("apply = " + apply);
}
默认方法 compose
public static void main(String[] args) {
sayMessageTwo((msg)->{
return msg*msg;
},msg2 ->{
return msg2*5;
});
sayMessageAndThen((msg)->{
return msg*msg;
},msg2 ->{
return msg2*5;
});
}
public static void sayMessageTwo(Function<Integer,Integer> f1,Function<Integer,Integer> f2){
/* * 1. 100 * 5 = 500 500 * 500 = 250000 */
Integer apply = f1.compose(f2).apply(100);
System.out.println("apply = " + apply);
}
public static void sayMessageAndThen(Function<Integer,Integer> f1,Function<Integer,Integer> f2){
/* * 1. 100 * 100 = 10000 5 * 10000 = 50000 */
Integer apply = f1.andThen(f2).apply(100);
System.out.println("applyThen = " + apply);
}
apply = 250000
applyThen = 50000
compose 方法和 andThen方法的区别就是:
A.compose(B) 以B的结果作为值传入去获取A的结果
A.andThen(B) 是先获取到A的结果作为参数 去获取B的结果
3. Predicate 有入参有返回值为 boolean类型
@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);
}
使用:
public static void main(String[] args) {
sayMessageTwo((msg)->{
return msg>8;
});
}
public static void sayMessageTwo(Predicate<Integer> predicate){
boolean test = predicate.test(9);
System.out.println("apply = " + test);
}
apply = true
默认方法 :and() 同时满足
negate()不满足
or() 有一个满足
ublic static void main(String[] args) {
sayMessageTwo((msg)->{
return msg>8;
},msg2->{
return msg2<8;
});
}
public static void sayMessageTwo(Predicate<Integer> p1,Predicate<Integer> p2){
boolean test = p1.and(p2).test(9);
boolean test1 = p1.or(p2).test(9);
boolean test2 = p1.negate().test(9);
System.out.println("test = " + test);
System.out.println("test1 = " + test1);
System.out.println("test2 = " + test2);
}
test = false
test1 = true
test2 = false
静态方法:isEqual ()
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
使用:
public static void main(String[] args) {
Predicate<Object> java = Predicate.isEqual("java");
boolean test = java.test("C++");
System.out.println("test = " + test);
}
结果:
test = false
基本常用的函数式接口就介绍到这啦 。。明天见🥰🥰🥰