函数式接口详解
函数式接口
以前一直好奇java能不能传参的时候参数为方法,现在通过函数式接口可以做到了。以前一直用的不多,最近用到了就做一个简单的汇总以及演示demo。
1.什么是函数式接口?
- 只包含一个抽象方法的接口,称为函数式接口
- 你可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)
- 我们可以在任意函数式接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口,同时javadoc也会包含一条声明,说明这个接口是一个函数式接口
2.自定义函数
package function;
/**
* @Description todo
* @Author cz
* @Date 2022/3/4
*/
public class Function {
@FunctionalInterface
public interface Func<T> {
T get();
}
public static class FuncImpl implements Func<Integer> {
@Override
public Integer get() {
return 3;
}
}
public static Integer getInteger(Func<Integer> func) {
return func.get();
}
public static void testFunc(){
//匿名内部类的方式
System.out.println(getInteger(new Func<Integer>() {
@Override
public Integer get() {
return 3;
}
}));
//Lambda形式
System.out.println(getInteger(() -> 3));
//实现类的方式
System.out.println(getInteger(new FuncImpl()));
}
public static void main(String[] args) {
//测试Function
testFunc();
}
}
3.JAVA内置四大核心函数式接口
在学习lambda表达式的时候,我们知道,要使用lambda表达式,我们就要创建一个函数式接口,那每次用lambda表达式的时候岂不是很麻烦,这时候,java给我们内置了四大核心函数式接口。
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer |
T | 无 | 对类型为T的对象应用操作,包含方法:void accept(T t) |
Supplier |
无 | T | 返回类型为T的对象,包含方法:T get() |
Function<T, R> 函数型接口 | T | R | 对类型为T的对象应用操作,并返回结果,结果是R类型的对象,包含方法:R apply(T t) |
Predicate |
T | boolean | 确定类型为T的对象是否满足某约束,并返回boolean值。包含方法boolean test(T t) |
还有一些其他接口可看参照里面的官方jdk文档里面,或是直接看 java.util.function 包下面的接口
4.四大接口示例
4.1 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); };
}
}
void accept(T t)
public static class ConsumerAcceptImpl implements Consumer<String> {
@Override
public void accept(String s) {
System.out.println(s);
}
}
public static void testConsumerAccept(String name, Consumer<String> consumer){
//do something with name
//then consumer the name
String helloName = String.format("hello %s", name);
consumer.accept(helloName);
}
public static void testAcceptMain(){
//lambda表达式
testConsumerAccept("张三", System.out::println);
//Consumer的实现类
testConsumerAccept("张三", new ConsumerAcceptImpl());
//匿名内部类
testConsumerAccept("张三", new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
}
Consumer
public static void testConsumerAndThen() {
Consumer<Student> c1 = (Student s) -> System.out.printf("%s:%s%n","c1", s.getSchool());
Consumer<Person> c2 = (Person p) -> System.out.printf("%s:%s%n", "c2", p.getName());
Consumer<Student> c3 = c1.andThen(c2);
Student s = new Student("s1的school", new Person("p", 11));
s.setName("student父类person的属性name");
c3.accept(s);
}
/* 运行结果
c1:s1的school
c2:student父类person的属性name
返回一个 consumer 的accept 为 先执行c1的accept然后执行c2的accept
*/
4.2 Supplier:共给型接口
@FunctionalInterface
public interface Supplier<T> {
T get();
}
T get( )
//需求:产生指定个数的整数,并放入集合中
public static List<Integer> getNumList(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for(int i=0;i<num;i++) {
Integer n = sup.get();
list.add(n);
}
return list;
}
public static void testSupplierGet() {
List<Integer> numList = getNumList(10, ()->(int)(Math.random()*100 ));
for (Integer integer : numList) {
System.out.println(integer);
}
}
4.3 Function<T,R>:函数型接口
@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;
}
}
R apply(T t)
//需求:用于处理字符串
public static String strHandler(String str, Function<String,String> fun) {
System.out.println("这里先处理,然后交给fun处理,这里的处理算是strHandler处理的。");
return fun.apply(str);
}
/*
对类型为T的对象应用操作返回类型为R的对象
*/
public static void testFunctionApply() {
String trimStr=strHandler("\t\t你好,world ",(str) -> {
System.out.println("这里算是fun处理的,需要返回值");
return str.trim();
});
System.out.println(trimStr);
}
Function<T,V> compose(Function<? super V, ? extends T> before)
public static void testFunctionCompose(){
Function<String, String> before = String::trim; //对入参的String进行trim操作,返回trim以后的String;
Function<String, String> f2 = str -> str.replace("hello", "你好"); //对入参的String里面的hello替换为你好
String rt = f2.compose(before).apply("hello, world ");
System.out.println(rt);
/* 此处compose的作用其实就是将多个Function的apply方法连接在一起用,compose里面的将Function的apply方法将提前于它的调用的那个
Function的apply方法。看成是过滤器会很好理解。
上述执行过程是 compose返回的Function f3.apply(f2.apply(before.apply(str)))
*/
}
Function<T, V> andThen(Function<? super R, ? extends V> after)
public static void testFunctionAndThen(){
Function<String, String> after = String::trim; //对入参的String进行trim操作,返回trim以后的String;
Function<String, String> f2 = str -> str.replace("hello", "你好"); //对入参的String里面的hello替换为你好
String rt = f2.andThen(after).apply("hello, world ");
System.out.println(rt);
/* 此处compose的作用其实就是将多个Function的apply方法连接在一起用,andThen里面的将Function的apply方法将后于它的调用的那个
Function的apply方法。看成是过滤器会很好理解。
上述执行过程是 andThen返回的Function f3.apply(after.apply(f2.apply(str)))
*/
}
Function<T, T> identity()
/* 测试 Function<T, T> identity() 用法
identity()返回的是一个入参和出参相同的Function*/
public static void printString(String str, Function<String, String> f1){
System.out.println(f1.apply(str));
}
public static void testFunctionIdentity(){
printString("s1", Function.identity());
}
4.4 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);
}
@SuppressWarnings("unchecked")
static <T> Predicate<T> not(Predicate<? super T> target) {
Objects.requireNonNull(target);
return (Predicate<T>)target.negate();
}
}
boolean test(T t) 用来处理参数T,看是否满足要求,可以理解为 条件A
public static void testPredicateTest(){
Predicate<Integer> predicateTest = x -> x > 0;
System.out.println(predicateTest.test(10));
}
//true
Predicate
public static void testPredicateAnd(){
Predicate<Integer> predicate = x -> x > 0;
Predicate<Integer> other = x -> x < 10;
System.out.println(predicate.and(other).test(11));
}
//flase
Predicate
public static void testPredicateNegate(){
Predicate<Integer> predicate = x -> x > 0;
System.out.println(predicate.negate().test(10));
}
//false
Predicate
public static void testPredicateOr(){
Predicate<Integer> predicate = x -> x > 0;
Predicate<Integer> other = x -> x < 0;
predicate.or(other).test(0);
}
//false
Predicate
public static void testPredicateIsEqual(){
Object obj = new Object();
Predicate.isEqual(obj).test(obj);
}
//true
Predicate
public static void testPredicateNot(){
Predicate<Integer> p1 = x -> x>0;
System.out.println(Predicate.not(p1).test(-1));
}
//true
5. 其他与Predicate相关的接口
-
BiPredicate<T, U>
针对两个参数,看两个参数是否符合某个条件表达式
-
DoublePredicate
看一个double类型的值是否符合某个条件表达式
-
IntPredicate
看一个int类型的值是否符合某个条件表达式
-
LongPredicate
看一个long类型的值是否符合某个条件表达式
参考:
1.https://www.jianshu.com/p/8005f32caf3d
2.https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/function/package-summary.html
3.https://www.jianshu.com/p/b38ff80e3039
4.源码地址:https://gitee.com/ashscc/java-ptn/tree/master/baseJDK/src/main/java/function
本文来自博客园,作者:orangeScc,转载请注明原文链接:https://www.cnblogs.com/ashScc/p/15972683.html