JDK8函数式接口Function、Consumer、Predicate、Supplier
备注1:观察发现,函数式接口下共有 1、三种方法 1.1 唯一的抽象方法 1.2 使用default定义普通方法(默认方法),通过对象调用。 实现接口后,因为默认方法不是抽象方法,所以可以不重写,但是如果开发需要,也可以重写 。当然如果接口中的默认方法不能满足某个实现类需要,那么实现类可以覆盖默认方法。签名跟接口default方法一致,但是不能再加default修饰符。 3.使用static定义静态方法,通过接口名调用。 2、一个新注解 如果现在某一个接口就是为了函数式接口而生的,定义的时候就让其只有一个抽象方法,所以有了一个新的注解:函数式接口@FunctionInterface
备注2:关于lambda表达式 JDK8以前,通过匿名内部类可以实现接口
Function
<Integer, String> fun
= new Function<Integer, String>() {
@Override
public String
apply(Integer t
) {
return String
.valueOf(t
);
}
};
JDK8中,通过lambda表达式实现
Function
<Integer, String> fun
= (x
) -> String
.valueOf(x
);
可以得出一个结论,lambda表达式就是为了优化匿名内部类而生。
String res
= fun
.apply(1000);
System
.out
.println(res
);
lambda表达式的性能最差也就和匿名内部类一样, 但是好的情况会更好。
案例demo:
package com
.lyj
.demo
.customTests
;
import com
.lyj
.demo
.functionInterface
.CustomerFunctionInterface
;
import org
.junit
.Test
;
import org
.junit
.runner
.RunWith
;
import org
.springframework
.test
.context
.junit4
.SpringJUnit4ClassRunner
;
import java
.util
.function
.Consumer
;
import java
.util
.function
.Function
;
import java
.util
.function
.Predicate
;
import java
.util
.function
.Supplier
;
@RunWith(SpringJUnit4ClassRunner
.class)
public class FunctionInterfaceTest {
@Test
public void functionTest() {
int originNum
= 10;
Function
<Integer, Integer> function
= value
-> value
+20;
System
.out
.println(function
.apply(originNum
));
Integer andThenApply
= function
.andThen(function
).apply(originNum
);
System
.out
.println(andThenApply
);
Integer composeValue
= function
.compose(function
).apply(originNum
);
System
.out
.println(composeValue
);
System
.out
.println(Function
.identity().apply(originNum
));
}
public int modifyValue(int originValue
, Function
<Integer, Integer> function
) {
return function
.apply(originValue
);
}
@Test
public void consumerTest() {
int num
= 10;
Consumer
<Integer> consumer
= value
-> System
.out
.println(value
+ 10);
consumer
.accept(num
);
consumer
.andThen(consumer
).accept(num
);
}
@Test
public void PredicateTest() {
int num
= 10;
Predicate
<Integer> predicate
= value
-> value
== 10;
Predicate
<Integer> predicate1
= value
-> value
> 20;
boolean predicateResultFlag
= predicate
.test(20);
System
.out
.println(predicateResultFlag
);
boolean test
= predicate
.and(predicate1
).test(num
);
System
.out
.println(test
);
boolean test1
= predicate
.or(predicate1
).test(num
);
System
.out
.println(test1
);
boolean test2
= predicate
.negate().test(10);
System
.out
.println(test2
);
}
@Test
public void supplierTest() {
String item
= "aaa";
Supplier
<String> supplier
= () -> item
+"无参返回";
System
.out
.println(supplier
.get());
}
@Test
public void customerTest() {
CustomerFunctionInterface customerFunctionInterface
= (a
, b
, c
) -> a
+b
+c
;
int opertateThree
= customerFunctionInterface
.opertateThree(1, 2, 3);
System
.out
.println(opertateThree
);
}
}
自定义函数式接口使用
自定义函数式接口注解
package com
.lyj
.demo
.annotation
;
import java
.lang
.annotation
.Documented
;
import java
.lang
.annotation
.ElementType
;
import java
.lang
.annotation
.Retention
;
import java
.lang
.annotation
.RetentionPolicy
;
import java
.lang
.annotation
.Target
;
@Target(value
= {ElementType
.TYPE
})
@Documented
@Retention(RetentionPolicy
.RUNTIME
)
public @
interface FunctionInterface {
}
自定义函数式接口:
package com
.lyj
.demo
.functionInterface
;
import com
.lyj
.demo
.annotation
.FunctionInterface
;
@FunctionInterface
public interface CustomerFunctionInterface {
int opertateThree(int a
, int b
, int c
);
}
测试在上面demo里
总结:
其实上面的4个函数式接口,都有一个共同的特点,都使用了@FunctionInterface注解,所以这四个接口个人觉得只是按使用习惯归类好的有代表性的函数式接口,可以直接拿来使用,其实你也可以用@FunctionInterface注解自定义想要的函数式接口,比如接收3个参数,返回1个结果。