详解如何熟练使用java函数式接口

一、函数式接口的由来

我们知道使用Lambda表达式的前提是需要有函数式接口,而Lambda表达式使用时不关心接口名,抽象方法名。只关心抽象方法的参数列表和返回值类型。因此为了让我们使用Lambda表达式更加的方法,在JDK中提供了大量常用的函数式接口

package com.bobo.jdk.fun;

public class Demo01Fun {

    public static void main(String[] args) {
        fun1((arr)->{
            int sum = 0 ;
            for (int i : arr) {
                sum += i;
            }
            return sum;
        });
    }

    public static void fun1(Operator operator){
        int[] arr = {1,2,3,4};
        int sum = operator.getSum(arr);
        System.out.println("sum = " + sum);
    }
}

/**
 * 函数式接口
 */
@FunctionalInterface
interface Operator{

    int getSum(int[] arr);
}

二、函数式接口介绍

在JDK中帮我们提供的有函数式接口,主要是在 java.util.function 包中。

2.1 Supplier

无参有返回值的接口,对于的Lambda表达式需要提供一个返回数据的类型。

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

使用:

/**
 * Supplier 函数式接口的使用
 */
public class SupplierTest {

    public static void main(String[] args) {
        fun1(()->{
            int arr[] = {22,33,55,66,44,99,10};
            // 计算出数组中的最大值
            Arrays.sort(arr);
            return arr[arr.length-1];
        });
    }

    private static void fun1(Supplier<Integer> supplier){
        // get() 是一个无参的有返回值的 抽象方法
        Integer max = supplier.get();
        System.out.println("max = " + max);

    }
}

2.2 Consumer

有参无返回值得接口,前面介绍的Supplier接口是用来生产数据的,而Consumer接口是用来消费数据的,使用的时候需要指定一个泛型来定义参数类型

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);
}

使用:将输入的数据统一转换为小写输出

public class ConsumerTest {

    public static void main(String[] args) {
        test(msg -> {
            System.out.println(msg + "-> 转换为小写:" + msg.toLowerCase());
        });
    }

    public static void test(Consumer<String> consumer){
        consumer.accept("Hello World");
    }
}

默认方法:andThen

如果一个方法的参数和返回值全部是Consumer类型,那么就可以实现效果,消费一个数据的时候,首先做一个操作,然后再做一个操作,实现组合,而这个方法就是Consumer接口中的default方法 andThen方法

 default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }

具体的操作

public class ConsumerAndThenTest {

    public static void main(String[] args) {
        test2(msg1->{
            System.out.println(msg1 + "-> 转换为小写:" + msg1.toLowerCase());
        },msg2->{
            System.out.println(msg2 + "-> 转换为大写:" + msg2.toUpperCase());
        });
    }

    public static void test2(Consumer<String> c1,Consumer<String> c2){
        String str = "Hello World";
        //c1.accept(str); // 转小写
        //c2.accept(str); // 转大写
        //c1.andThen(c2).accept(str);
        c2.andThen(c1).accept(str);
    }
}

2.3 Function

有参有返回值的接口,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);
}

使用:传递进入一个字符串返回一个数字

public class FunctionTest {

    public static void main(String[] args) {
        test(msg ->{
            return Integer.parseInt(msg);
        });
    }

    public static void test(Function<String,Integer> function){
        Integer apply = function.apply("666");
        System.out.println("apply = " + apply);
    }
}

默认方法:andThen,也是用来进行组合操作,

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
public class FunctionAndThenTest {

    public static void main(String[] args) {
        test(msg ->{
            return Integer.parseInt(msg);
        },msg2->{
            return msg2 * 10;
        });
    }

    public static void test(Function<String,Integer> f1,Function<Integer,Integer> f2){
        /*Integer i1 = f1.apply("666");
        Integer i2 = f2.apply(i1);*/
        Integer i2 = f1.andThen(f2).apply("666");
        System.out.println("i2:" + i2);

    }
}

默认的compose方法的作用顺序和andThen方法刚好相反

而静态方法identity则是,输入什么参数就返回什么参数

2.4 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 class PredicateTest {

    public static void main(String[] args) {
        test(msg -> {
            return msg.length() > 3;
        },"HelloWorld");
    }

    private static void test(Predicate<String> predicate,String msg){
        boolean b = predicate.test(msg);
        System.out.println("b:" + b);
    }
}

在Predicate中的默认方法提供了逻辑关系操作 and or negate isEquals方法

package com.bobo.jdk.fun;

import java.util.function.Predicate;

public class PredicateDefaultTest {

    public static void main(String[] args) {
        test(msg1 -> {
            return msg1.contains("H");
        },msg2 -> {
            return msg2.contains("W");
        });
    }

    private static void test(Predicate<String> p1,Predicate<String> p2){
        /*boolean b1 = predicate.test(msg);
        boolean b2 = predicate.test("Hello");*/
        // b1 包含H b2 包含W
        // p1 包含H 同时 p2 包含W
        boolean bb1 = p1.and(p2).test("Hello");
        // p1 包含H 或者 p2 包含W
        boolean bb2 = p1.or(p2).test("Hello");
        // p1 不包含H
        boolean bb3 = p1.negate().test("Hello");
        System.out.println(bb1); // FALSE
        System.out.println(bb2); // TRUE
        System.out.println(bb3); // FALSE
    }
}

到此这篇关于详解如何熟练使用java函数式接口的文章就介绍到这了,更多相关java函数式接口内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java8函数式接口的基础学习教程

    函数式接口 1.1 函数式接口概述 函数式接口:有且仅有一个抽象方法的接口 Java中的函数式编程体现就是Lambda表达式,所以函数式接口就是可以使用与Lambda使用的接口 只有确保接口只能够有且只有一个抽象方法,Lambda才能顺利的进行推导 检测接口是不是函数式接口: @FunctionalInterface 放在接口定义的上方:如果接口是函数式接口,编译通过,反之失败. 注意: 我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算不写,只要爆炸慢煮函数式

  • 详解JAVA8 函数式接口

    写在前面 Java8中内置了一些在开发中常用的函数式接口,极大的提高了我们的开发效率.那么,问题来了,你知道都有哪些函数式接口吗? 函数式接口总览 这里,我使用表格的形式来简单说明下Java8中提供的函数式接口. 四大核心函数式接口 首先,我们来看四大核心函数式接口,如下所示. 函数式接口 参数类型 返回类型 使用场景 Consumer消费型接口 T void 对类型为T的对象应用操作,接口定义的方法:void accept(T t) Supplier供给型接口 无 T 返回类型为T的对象,接口

  • Java8简单了解Lambda表达式与函数式接口

    Java8被称作Java史上变化最大的一个版本.其中包含很多重要的新特性,最核心的就是增加了Lambda表达式和StreamAPI.这两者也可以结合在一起使用.首先来看下什么是Lambda表达式. 使用Lambda表达式不仅让代码变的简单.而且可读.最重要的是代码量也随之减少很多.然而,在某种程度上,这些功能在Scala等这些JVM语言里已经被广泛使用. 并不奇怪,Scala社区是难以置信的,因为许多Java 8里的内容看起来就像是从Scala里搬过来的.在某种程度上,Java 8的语法要比Sc

  • Java 8新特性 内建函数式接口详解

    Java 8新特性内建函数式接口 在之前的一片博文 Lambda 表达式,提到过Java 8提供的函数式接口.在此文中,将介绍一下Java 8四个最基本的函数式接口 对于方法的引用,严格来讲都需要定义一个接口.不管我们如何操作实际上有可能操作的接口只有四种. Java 8 提供了函数式接口包java.util.function.*,在该包下有许多Java 8内建的函数式接口.不过基本上分为四种基本的: 功能型接口 (Function) 将 T 作为输入,返回 R 作为输出,他还包含了和其他函数组

  • Java函数式接口Supplier接口实例详解

    这篇文章主要介绍了Java函数式接口Supplier接口实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 JDK提供了大量常用的函数式接口以丰富Lambda的典型使用场景,它们主要在 java.util.function 包中被提供. 下面是最简单的Supplier接口及使用示例. Supplier接口概述 // Supplier接口源码 @FunctionalInterface public interface Supplier<T>

  • Java Lambda表达式和函数式接口实例分析

    本文实例讲述了Java Lambda表达式和函数式接口.分享给大家供大家参考,具体如下: 一 点睛 Lambda表达式的类型,也称为"目标类型",Lambda表达式的目标类型必须是函数式接口.函数式接口代表只包含一个抽象方法的接口.函数式接口可以包含多个默认方法.类方法,但只能声明一个抽象方法. 如果采用匿名内部类语法来创建函数式接口的实例,只要实现一个抽象方法即可,在这种情况下即可采用Lambda表达式来创建对象,该表达式创建出来的对象的目标类型就是这个函数式接口. Java 8专门

  • JAVA8之函数式编程Function接口用法

    从这章开始,会介绍几个常用的函数式接口工具,首先先来看下这个大家族: 首先从Function接口开始介绍 一. 概述 该接口顾名思义,函数的意思,就像是数学,是给定一个参数然后返回结果.该类方法如下: package java.util.function; import java.util.Objects; @FunctionalInterface public interface Function<T, R> { R apply(T t); default <V> Functio

  • 详解如何熟练使用java函数式接口

    一.函数式接口的由来 我们知道使用Lambda表达式的前提是需要有函数式接口,而Lambda表达式使用时不关心接口名,抽象方法名.只关心抽象方法的参数列表和返回值类型.因此为了让我们使用Lambda表达式更加的方法,在JDK中提供了大量常用的函数式接口 package com.bobo.jdk.fun; public class Demo01Fun { public static void main(String[] args) { fun1((arr)->{ int sum = 0 ; for

  • 详解 Corba开发之Java实现Service与Client

    详解 Corba开发之Java实现Service与Client 1      概述 CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构)是由OMG组织制订的一种标准的面向对象应用程 序体系规范.或者说 CORBA体系结构是OMG为解决分布式处理环境(DCE)中,硬件和软件系统的互连而提出的一种解决方案. OMG:Object Management Group,对象管理组织.是一个国际化的.开放成员的.非盈利性的计算机行业标准协

  • 详解Springboot如何通过注解实现接口防刷

    目录 前言 1.实现防刷切面PreventAop.java 1.1 定义注解Prevent 1.2 实现防刷切面PreventAop 2.使用防刷切面 3.演示 前言 本文介绍一种极简洁.灵活通用接口防刷实现方式.通过在需要防刷的方法加上@Prevent 注解即可实现短信防刷: 使用方式大致如下: /** * 测试防刷 * * @param request * @return */ @ResponseBody @GetMapping(value = "/testPrevent") @P

  • Java BigDecimal详解_动力节点Java学院整理

    1.引言 借用<Effactive Java>这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合.但是,商业计算往往要求结果精确,例如银行存款数额,这时候BigDecimal就派上大用场啦. 2.BigDecimal简介 BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组

  • 详解Swift中对C语言接口缓存的使用以及数组与字符串转为指针类型的方法

    详解Swift中对C语言接口缓存的使用以及数组与字符串转为指针类型的方法 由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与UnsafeMutablePointer类型,分别对应为const Type*类型与Type *类型. 而在Swift编程语言中,由于一般数组(Array)对象都无法直接用于C语言中含有指针类型的函数参数(比如:void*),所以往往需要

  • Java System类详解_动力节点Java学院整理

    System类是jdk提供的一个工具类,有final修饰,不可继承,由名字可以看出来,其中的操作多数和系统相关.其功能主要如下: • 标准输入输出,如out.in.err • 外部定义的属性和环境变量的访问,如getenv()/setenv()和getProperties()/setProperties() • 加载文件和类库的方法,如load()和loadLibrary(). • 一个快速拷贝数组的方法:arraycopy() • 一些jvm操作,如gc().runFinalization()

  • Java Runtime类详解_动力节点Java学院整理

    一.概述 Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接.一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用.一旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控制Java虚拟机的状态和行为. 当不被信任的代码调用任何Runtime方法时,常常会引起SecurityExc

  • Java Scaner类详解_动力节点Java学院整理

    Java.util.Scanner是Java5.0的新特征,主要功能是简化文本扫描.这个类最实用的地方表现在获取控制台输入,其他的功能都很鸡肋,尽管Java API文档中列举了大量的API方法,但是都不怎么地. 一.扫描控制台输入  这个例子是常常会用到,但是如果没有Scanner,你写写就知道多难受了. 当通过new Scanner(System.in)创建一个Scanner,控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给Scanner,作为扫描对象.如果要获取输入的内容,则只需要

  • 详解json string转换为java bean及实例代码

    详解json string转换为java bean及实例代码 pom中添加如下两个库: <dependency> <groupId>org.codehaus.jackson </groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.2</version> <scope>provided</scope> </depende

随机推荐