java代码之美(14)---Java8 函数式接口

Java8 函数式接口

之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda

函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加简洁。

一、概念

1、什么是函数式接口

概念 所谓的函数式接口, 当然首先是一个接口, 然后就是在这个接口里面 只能有一个抽象方法

有关函数式接口,有个专门的注解叫:@FunctionalInterface。该注解主要特点有:

1、该注解只能标记在"有且仅有一个抽象方法"的接口上,表示函数式接口。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承 java.lang.Object,所以如果接口显示声明覆盖了Object中的方法,那么也不算抽象方法。
4、允许java.lang.Object中的public方法
5、该注解不是必须的,如果一个接口符合"函数式编程"定义,那么加不加该注解都没有影响。加上该注解能够 更好地让编译器进行检查,
如果编写的不是函数式接口,但是加上了@FunctionalInterface 那么编译器会报错。

2、示例

1) 正确示例

/**
 * 函数式接口注解
 */
@FunctionalInterface
public interface PersonInterface {
    /**
     * 1、仅有一个抽象方法
     */
     void say();

    /**
     * 2、java.lang.Object中的方法不算
     */
    @Override
     boolean equals(Object var1);

    /**
     * 3、java8 接口才可以有默认的方法实现 前提是方法名称必须使用default关键字修饰
     */
     default void defaultMethod() {
        System.out.println("haha");
    }

    /**
     * 4、静态方法
     */
     static void staticMethod() {
    }
}

2) 错误示例

加上@FunctionInterface,就代表该接口是函数式接口,只能有一个抽象方法,如果有多个编译时就会直接报错。

3、为什么只能有一个抽象方法

其实这个问题很好去理解,上面说了函数式接口主要是为Lambda语法服务的,为了让代码看去更加简洁。

下面通过示例来说明

     public static void main(String[] args) {
       //上面的接口 通过Lambda表达式重新 say方法
        PersonInterface inter = () -> System.out.println("我说什么好呢?");
        inter.say();
        //控制台输出: 我说什么好呢?
    }

通过 函数式接口 + Lambda表达式 让代码看去变的简洁,而这里的关键点在于:

 ()->{} 就是代表对say()方法的重写

如果你有个多个抽象方法, 那么()-> {} 这种写法,编译器就不知道这是重写的哪个方法了。所以这就是为什么只能有一个抽象方法的原因。

二、综合示例

这里再举一个综合示例,来方便理解它们。

自定义函数式接口

/**
  * 自定义函数TestFunction,提供handler接口, 传入的是A,返回的是B
  */
@FunctionalInterface
public interface MyFunction<A, B> {

    /**
      * @Description: 传入的是A 返回的是B
      */
    B handler(A a, A a1);
}

Student对象

public class Student {
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;

    //省略 set get toString 全参数构造函数 无参构造函数
  }

测试类

   public static void main(String[] args) {
        //1、求和 传入Integer返回Integer类型
        MyFunction<Integer, Integer> myFunction1 = (x, y) -> {
            //返回总和
            return x + y;
        };
        Integer count = myFunction1.handler(5, 10);
        System.out.println("输出总和为:" + count);

        //2、求和 传入Integer返回String类型
        MyFunction<Integer, String> myFunction2 = (x, y) -> {
            //返回总和
            return x + " + " + y + " = " + (x + y);
        };
        System.out.println(myFunction2.handler(5, 10));

        //3、对象处理 过滤对象
        List<Student> students = Arrays.asList(new Student("小明", 3), new Student("小白", 13), new Student("小黄", 18));
        MyFunction<Integer, List<Student>> myFunction3 = (x, y) -> {
            //这里通过java8 的stream来过滤 年龄大于x 且小于y的对象
            List<Student> studentList = students.stream().filter(student -> student.getAge() > x && student.getAge() < y).collect(Collectors.toList());
            return studentList;
        };

        List<Student> list = myFunction3.handler(5, 15);
        //遍历集合 输出对象
        list.forEach(x -> System.out.println(x));
    }

运行结果

从运行结果可以很明显看出,集合对象经过过滤只剩下一个满足条件的了。

你如果愿意有所作为,就必须有始有终。(24)

原文地址:https://www.cnblogs.com/qdhxhz/p/12046505.html

时间: 2024-10-10 01:22:24

java代码之美(14)---Java8 函数式接口的相关文章

java代码之美(16) ---Java8 Optional

摘自:https://www.cnblogs.com/qdhxhz/p/12056745.html Java8 Optional 一句话介绍Optional类:使用JDK8的Optional类来防止NullPointerException(空指针异常)问题. 一.前言 在我们开放过程中,碰到的异常中NullPointerException必然是排行第一的.所以在平时编码中,我们会时时的判断null. public void saveCity(City city) { if (city != nu

【java代码之美】---Java8 Stream

Stream 第一次看到Stream表达式就深深把我吸引,用它可以使你的代码更加整洁而且对集合的操作效率也会大大提高,如果你还没有用到java8的Stream特性,那就说明你确实out啦. 一.概述 1.什么是Stream Stream是一种可供流式操作的数据视图有些类似数据库中视图的概念它不改变源数据集合如果对其进行改变的操作它会返回一个新的数据集合. 总的来讲它有三大特性:在之后我们会对照着详细说明        1.stream不存储数据        2.stream不改变源数据    

【java代码之美】---Java8 Map中的computeIfAbsent方法

Map中的computeIfAbsent方法 Map接口的实现类如HashMap,ConcurrentHashMap,HashTable等继承了此方法,通过此方法可以在特定需求下,让你的代码更加简洁. 一.案例说明 1.概述 在JAVA8的Map接口中,增加了一个方法computeIfAbsent,此方法签名如下: public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) 此方法首先判断缓存

Java8函数式接口以及lambda表达式实践

最近重新深入了解和学习了Java8的函数式接口以及lambda表达式,发现以前写的代码大多都是伪-函数表达式,因此重新精炼了一下的这部分代码,仅供参考,如有更好的方式,欢迎在评论区留言. 1.计算订单总金额 订单总金额一般是在后台循环叠加每个购买商品的金额已获取到,通常的方式如下 BigDecimal totalAmount = new BigDecimal(0); for (VenditionProduct venditionProduct : venditionVo.getVendition

[二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口

函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type used to indicate that an interface * type declaration is intended to be a <i>functional interface</i> as * defined by the Java Language Specificat

java8函数式接口(Functional Interface)

介绍 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为 lambda 表达式(箭头函数). 函数式接口代表的一种契约, 一种对某个特定函数类型的契约.Lambda表达式不能脱离上下文而存在,它必须要有一个明确的目标类型(interface),而这个目标类型就是某个函数式接口. java8之前已经存在的函数式接口有很多,比如java.lang.Runnable.java.util.concurrent.

Java8函数式接口简介

一.函数式接口 1. 可以使用注解@FunctionalInterface 2. 函数式接口有且仅有一个抽象方法:如果一个接口里只有一个抽象方法,这个接口可以作为函数式接口 3. 可以有0个或多个非抽象方法 4. 可以被隐式转换为lambda表达式 5. 函数式接口的实例 a. lambda表达式:提供参数列表,代码块主体,必须依附于函数式接口的实例对象 b. 方法引用,把函数当参数使用 6. java8允许在接口中加入具体方法/default方法/static方法,default方法 二.Su

Java8函数式接口/Lambda表达式/接口默认方法/接口静态方法/接口冲突方法重写/lambda表达式指定泛型类型等

一:函数式接口 1.函数式接口的概念就是此接口必须有且只能有一个抽象方法,可以通过@FunctionalInterface来显示规定(类似@Override),但是没有此注解的但是只有一个抽象方法的接口也是函数式接口:(接口也和类一样有包访问权限,但是内部的方法则默认是public) @FunctionalInterface public interface IFoo{ void print(); }  // 就是一个最简单的函数式接口,但是如果再有个如void print2()抽象方法则这个接

【java代码之美】---guava之Immutable(不可变)集合

Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类. Guava中不可变对象和Collections工具类的unmodifiableSet/List/Map/etc的区别: 当Collections创建的不可变集合的wrapper类改变的时候,不可变集合也会改变,而Guava的Immutable集合保证确实是不可变的. 1.JDK中实现immuta