JDK8中的函数式接口功能分析与demo

2021-12-07 16:44:35 浏览数 (1)

JDK 8最鲜明的特性就是加入了lambda表达式,该特性最大的不同就是将原有的匿名内部类以语法糖的形式作为入参进入方法,所以Lambda表达式必须兼容函数式接口

Consumer

消费型接口,通过传入参数输出值,可以理解为定义了一个void方法处理数据,如果出现异常,则把异常转发给调用者。

例如forEach

Supplier

Optional.orElseGet()方法入参就是Supplier,如果存在值,通过Supplier容器存储该值并通过其get方法返回。

Predicate

谓词表达的是一种关系,其作用是判断。

代码语言:javascript复制
        Predicate<Integer> predicate = new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                if (integer > 5) {
                    return true;
                }
                return false;
            }
        };
        Stream<Integer> stream = Stream.of(1, 23, 3, 4, 5, 56, 6, 6);

		//以上代码相当于
        List<Integer> lists = stream.filter(i -> i > 5).collect(Collectors.toList());

i->i>5;就相当于一个Predicate对象, i-> i>5 中的 ->是一个语法糖,是lambda的写法, (parameters) -> expression 或 (parameters) ->{ statements; }

Function

功能型接口,作用是类型转换,将输入数据转换成另一种形式输出。

代码语言:javascript复制
public void test_Function() {
    Function<String, Integer> function = new Function<String, Integer>() {
        @Override
        public Integer apply(String s) {
            //重写Function的apply方法,获取字符串的长度,将String类型转化为Integer类型
            //Function中第一个泛型是当前类型,第二个Integer是转换为后的类型
            return s.length();
        }
    };

    Stream<String> stream = Stream.of("aaa", "bbbbb", "ccccccv");
    Stream<Integer> stream1 = stream.map(function);
    stream1.forEach(System.out::println);
    System.out.println("********************");

    ArrayList<String> stringArrayList = new ArrayList<>();
    stringArrayList.add("aaaaaaaa");
    stringArrayList.add("bbbbb");
    stringArrayList.add("ccc");
    stringArrayList.add("dd");
    //使用lambda的写法
    //Stream.map()将当前类型转化为其他类型
    List<Integer> collect = stringArrayList.stream().map(String::length).collect(Collectors.toList());
    System.out.println(collect);
}

使用map方法,Function为入参,将String类型转化为Integer。

该API常用于获取List中单一属性值的场景。

自定义函数式接口

使用@FunctionalInterface定义一个函数式接口,入参是一个泛型T,结果类R

代码语言:javascript复制
@FunctionalInterface
public interface MyFunc<T, R> {
    R getValue(T t1, T t2);
}

实现类

代码语言:javascript复制
@Slf4j
public class TestClass {

    public void operate(Long num1, Long num2, MyFunc<Long, Long> myFunc) {
        Long value = myFunc.getValue(num1, num2);
        System.out.println(value);
    }

    @Test
    public void test4() {

        operate(100L, 299L, new MyFunc<Long, Long>() {
            @Override
            public Long getValue(Long t1, Long t2) {
                //匿名内部类实现MyFun接口
                return t1   t2;
            }
        });

        operate(100L, 299L, (x, y) -> x   y);


        log.debug("===================乘法实现=====================");

        //乘法的接口实现
        operate(100L, 200L, new MyFunc<Long, Long>() {
            @Override
            public Long getValue(Long t1, Long t2) {
                return t1*t2;
            }
        });

        operate(100L,200l,(X,Y)->X*Y);
    }
}

test4:

定义一个入参是Long类型、以及将函数式接口传入operate方法中,使用匿名内部类做MyFunc函数式接口中的getValue()方法实现,实现类中返回t1 t2(两个入参的值)。

代码语言:javascript复制
operate(100L, 299L, (x, y) -> x   y);

使用lambda表达式写法替换匿名内部类的形式,入参自动匹配类型,并返回入参x y。

0 人点赞