Java 8 常见函数式接口使用简单示例

简介

JDK 1.8 API包含了很多内建的函数式接口。之所以提供这些接口,是因为它们有比较多的使用场景,通过结合使用lambda表达式,我们可以很方便地利用这些接口将一些逻辑作为变量传递甚至组合起来实现更为复杂的逻辑,就像我们将一些普通类对象作为变量传递或者组合起来一样方便。

这里我们对一些常用的函数式接口给出一些简单的使用例子,方便你理解这些接口的意义,也在想使用它们的时候,知道怎样使用。

接口介绍
Consumer<T>消费函数:接收一个类型为T的参数,基于它进行某种计算,但并不返回任何结果
Predicate<T>一元断言函数/一元谓词函数:接收一个类型为T的参数,进行某种断言计算,返回一个类型为boolean的结果
Function<T, R>一元函数:接收一个类型为T的参数,进行某种计算,返回一个类型为R的结果
BiFunction<T, U, R>二元函数:接收两个参数,一个类型为T,一个类型为U,进行某种计算,返回一个类型为R的结果
Supplier<T>提供者函数:经过某种计算,提供一个类型为T的对象,但是不需要参数
该接口在一些需要惰性求值的场合非常实用。
比如有些结果对象计算非常复杂耗时但却能保持一段时间不变,这种情况下你就可以在首次get()调用时
才计算和创建结果数据对象,将其缓存后返回该结果对象,之后再次get()时都可以复用已经缓存的对象
UnaryOperator一元运算符::接收一个类型为T的参数,返回一个同类型的结果
可以由Function<T,R>实现同样功能,
实际上继承自Function<T,R>并且要求其中T,R相同
BinaryOperator二元运算符:接受两个类型都是T的参数,返回一个同类型的结果
可以由BiFunction<T,U,R>实现同样功能,
实际上继承自BiFunction<T,U,R>并且要求其中T,U,R相同

代码示例

package test.functional;

import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.*;

/**
 * Using Java 8 Functional interfaces as lambda expressions
 */
@Slf4j
public class Java8FunctionalDemo<T> {

    /**
     * 输入一个指定类型的参数,基于此参数进行某种计算,但是并不返回任何结果
     */
    public static void demoConsumer() {
        Consumer<List<String>> counter = list -> {
            int number = list.size();
            log.info("Consumer<T>-The list {} has {} elements", list, number);
        };

        String[] words = {"Tom", "and", "Jerry"};
        counter.accept(Arrays.asList(words));
    }

    /**
     * Function 函数式接口, 输入指定类型的参数,经过计算,
     * 返回另外某个指定类型的结果。 输入参数的类型和返回结果
     * 的类型可以相同也可以不同。
     */
    public static void demoFunction() {
        {//例子: 计算某个整数的平方
            // 特点 : 入参类型T和结果类型R可以一样
            Function<Integer, Integer> square = i -> i * i;

            int root = 9;
            int result = square.apply(root);// 注意这里入参类型是Integer,返回值类型也是 Integer
            log.info("Function<T,T>-Square of {} is : {}", root, result);
        }


        {// 例子 : 求字符串的长度
            // 特点 : 入参类型T和结果类型R可以不一样
            Function<String, Integer> length = s -> s.length();
            String string = "Hello World!";
            int result = length.apply(string); // 注意这里入参类型是String,返回结果类型是 Integer
            log.info("Function<T,R>-Length of string '{}; is : {}", string, result);
        }
    }

    /**
     * BiFunction 函数式接口, 输入指定类型为T,Y的两个参数,经过计算,
     * 返回另外某个指定类型为R的结果。 两个输入参数的类型和返回结果的类型三者
     * 可以相同也可以不同。
     */
    public static void demoBiFunction() {
        {//例子: 计算两个整数的和
            // 特点 : 入参类型T和结果类型T一样
            BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b;

            int a = 9;
            int b = 10;
            int result = sum.apply(a, b);// 注意这里两个入参类型都是Integer,返回值类型也是 Integer
            log.info("BiFunction<T,T,T>-Sum of {},{} is : {}", a, b, result);
        }

        {// 例子 : 获取一组名字中某种姓氏的名字的个数
            BiFunction<List<String>, String, Long> count = (data, filter) -> {
                long counter = data.stream().filter((e) -> e.startsWith("王")).count();
                return counter;
            };

            String[] names = {"王刚", "谢胜武", "张三丰", "刘德财", "张德帅", "王梦云"};
            String familyName = "王";
            // 注意这里 T,U,R 分别是 : List<String>,String,Long
            long counter = count.apply(Arrays.asList(names), familyName);
            log.info("BiFunction<T,U,R>-这群人{}里面,老{}家来了{}个人", names, familyName, counter);
        }
    }

    static void demoSupplier() {
        //  不需要提供参数,每次总是返回同一个常量
        Supplier<String> constValueSupplier = () -> "hello world";
        log.info("Supplier<T>-提供常量值 : {}", constValueSupplier.get());

        //替代不接受参数的工厂方法
        Supplier<LocalDateTime> factorySupplier = () -> LocalDateTime.now();
        log.info("Supplier<T>-代替工厂方法,提供对象 : {}", factorySupplier.get());

        //java 的new 方法不接受参数但是能返回一个结果对象,所以可以用一个 supplier替代
        Supplier<Date> asNewSupplier = Date::new;
        log.info("Supplier<T>-代替类的new方法,提供对象 : {}", asNewSupplier.get());
    }

    /**
     * 一元操作符,输入一个指定类型为T的参数,返回一个同样类型的结果,
     * 实际上继承自Function<T,R>,只是限制了其中的T,R必须相同
     */
    public static void demoUnaryOperator() {
        {//例子: 计算某个整数的平方
            // 特点 : 入参类型T和结果类型T一样
            UnaryOperator<Integer> square = i -> i * i;

            int root = 9;
            int result = square.apply(root);// 注意这里入参类型是Integer,返回值类型也是 Integer
            log.info("UnaryOperator<T>-Square of {} is : {}", root, result);
        }
    }

    /**
     * 二元操作符,输入两个指定类型为T的参数,返回一个同样类型的结果,
     * 实际上继承自BiFunction<T,U,R>,只是限制了其中的T,U,R必须相同
     */
    public static void demoBinaryOperator() {
        {//例子: 计算两个整数的和
            // 特点 : 入参类型T和结果类型T一样
            BinaryOperator<Integer> sum = (a, b) -> a + b;

            int a = 9;
            int b = 10;
            int result = sum.apply(a, b);// 注意这里两个入参类型都是Integer,返回值类型也是 Integer
            log.info("BinaryOperator<T>-Sum of {},{} is : {}", a, b, result);
        }
    }

    /**
     * 输入一个指定类型为T的参数,基于它执行某种断言逻辑,给出一个 true/false 结论
     */
    public static void demoPredicate() {
        {//例子: 判断入参表示的某种动物是否是狗
            // 特点 : 入参类型T和结果类型T一样
            Predicate<String> isDog = type -> type.equalsIgnoreCase("dog");

            String animal1 = "dog";
            boolean animal1IsDog = isDog.test(animal1);// 注意这里入参类型是String,返回值类型也是 boolean
            log.info("Predicate<T>-{} is a dog : {}", animal1, animal1IsDog);

            String animal2 = "cat";
            boolean animal2IsDog = isDog.test(animal2);// 注意这里入参类型是String,返回值类型也是 boolean
            log.info("Predicate<T>-{} is a dog : {}", animal2, animal2IsDog);
        }
    }

    public static void main(String[] args) {
        demoFunction();

        demoBiFunction();

        demoConsumer();

        demoSupplier();

        demoPredicate();

        demoUnaryOperator();

        demoBinaryOperator();
    }
}

输出结果如下所示:

Function<T,T>-Square of 9 is : 81
Function<T,R>-Length of string 'Hello World!; is : 12
BiFunction<T,T,T>-Sum of 9,10 is : 19
BiFunction<T,U,R>-这群人[王刚, 谢胜武, 张三丰, 刘德财, 张德帅, 王梦云]里面,老王家来了2个人
Consumer<T>-The list [Tom, and, Jerry] has 3 elements
Supplier<T>-提供常量值 : hello world
Supplier<T>-代替工厂方法,提供对象 : 2018-12-01T22:38:15.799
Supplier<T>-代替类的new方法,提供对象 : Sat Dec 01 22:38:15 CST 2018
Predicate<T>-dog is a dog : true
Predicate<T>-cat is a dog : false
UnaryOperator<T>-Square of 9 is : 81
BinaryOperator<T>-Sum of 9,10 is : 19
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值