澳门新葡亰娱乐网站-www.142net-欢迎您

澳门新葡亰娱乐网站是因为你还没有找到一条正确的致富之路,www.142net是将所有的游戏都汇集在一起的官方平台,因为澳门新葡亰娱乐网站这个网站当中有着大量的游戏攻略,托IP定位技术,传达终端直接到达的精准传播方式。

函数式编程初识之函数式接口,Java8函数式编程之

来源:http://www.bhtsgq.com 作者:计算机知识 人气:172 发布时间:2019-05-30
摘要:函数式接口 上壹篇博客Java8函数式编制程序之贰 : 拉姆da表达式 -简书 介绍了兰姆da表达式,最终也留下了三个标题,就是Lambda到底用在哪些地点,以及哪些是函数式接口? 怎么是函

函数式接口

上壹篇博客Java8函数式编制程序之贰 : 拉姆da表达式 - 简书 介绍了兰姆da表达式,最终也留下了三个标题,就是Lambda到底用在哪些地点,以及哪些是函数式接口?

怎么是函数式接口

Java 八引进了函数式接口的概念

​ 1). 只含有3个抽象方法的接口,称为函数式接口

​ 二). 函数式接口可以被隐式转变为lambda表明式。

​ 3). 在任性函数式接口上使用@FunctionalInterface注脚,那样做能够检查它是还是不是是三个函数式接口,同期javadoc 也会含有一条表明,表明这几个接口是一个函数式接口。

在Java8函数式编制程序初识之Lambda表明式中讲了要是2个接口中仅有二个待完毕的法子则它能够用拉姆da替代.大家把这种接口叫做函数式接口,大家得以在该接口上写上@FunctionalInterface表明表明它是个函数式接口,可是无论标不标,它都会被Java识别为函数式接口

概述:接口中唯有四个浮泛方法

上边介绍的只怕很空虚,精晓不了,至少在笔者眼里单独的那多少个借口是从没有过用的,跟最下边说的 Stream流一同用才会有作用

  • 函数式接口,即适用于函数式编制程序场景的接口。而Java中的函数式编制程序彰显正是Lambda,所以函数式接口正是可
    以适用于拉姆da使用的接口。唯有保险接口中有且仅有二个虚幻方法,Java中的Lambda本事顺风地拓展推导。

    备注:“语法糖”是指利用特别有利,然则原理不改变的代码语法。比方在遍历群集时利用的for-each语法,其实
    底层的兑现原理仍旧是迭代器,那就是“语法糖”。从使用范围来说,Java中的拉姆da能够被作为是无名氏内部
    类的“语法糖”,不过两岸在常理上是差异的。

  • 格式:

    1. 壹旦确认保证接口中有且仅有三个架空方法就可以:

       修饰符 interface 接口名称 {
          public abstract 返回值类型 方法名称(可选参数信息);
          // 其他非抽象方法内容
       }
      
    2. @FunctionalInterface注解

      与@Override 申明的效益类似,Java 第88中学等职业学校门为函数式接口引进了3个新的注明: @FunctionalInterface 。该注
      解可用于三个接口的定义上,壹旦采纳该注脚来定义接口,编写翻译器将会强制检查该接口是不是真的有且仅有一个华而不实方法,不然将会报错。必要注
      意的是,固然不应用该注明,只要满足函数式接口的定义,那照旧是三个函数式接口,使用起来都同样。

    3. 自定义函数式接口(前边已经写过,那就不重复写了)

      package com.wzlove.function;

      /**

      • 自定义函数式接口
        • 选取@FunctionalInterface能够作证该接口是函数式接口,可是不加,倘若接口中唯有一个架空方法,这几个接口也是函数式接口
        • 约等于说函数式接口不以注脚的存在而存在
          */
          @FunctionalInterface
          public interface MyFunctionalInterface {

        public abstract void show();
        }

还记得大家在率先篇博客中定义的那个接口吗?

预约义的函数式接口

​ Java 八定义了大批量的约定义函数式接口,用于大规模类型的代码传递,这几个函数定义在包java.util.function下,

里头有四大主导函数式接口。

函数式接口 参数类型 返回类型 用途
Consumer<T>(消费型接口) T void 对类型为T的对象应用操作。void accept(T t)
Supplier<T>(供给型接口) T 返回类型为T的对象。 T get();
Function<T, R>(函数型接口) T R 对类型为T的对象应用操作并返回R类型的对象。R apply(T t);
Predicate<T>(断言型接口) T boolean 确定类型为T的对象是否满足约束。boolean test(T t);

Consumer<T> 消费型接口

public static void consume(double money, Consumer<Double> con){
    con.accept(money);
}
public static void main(String[] args) {
    consume(10000, (m) -> {
        System.out.println("今日全场8折");
        System.out.println("顾客消费:"   (m * 0.8)   "元");
    });
}

函数式编程初识之函数式接口,Java8函数式编程之三。Supplier<T> 必要型接口

//生成num个整数,并存入集合
public 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 main(String[] args) {
    //10个100以内的随机数
    List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
    for (Integer num : numList) {
        System.out.println(num);
    }
}

Function<T, 途达> 函数型接口

/*
    Function接口常用于数据的处理转换,比如给定一个员工列表,需要返回名称列表
*/
public class Employee {
    private int id;
    private String name;
    private double salary;
    public Employee(String name){
        this.name = name;
    }
    public Employee(String name,double salary) {
        this.name = name;
        this.salary = salary;
    }
    //省略getter setter
}
public class TestEmp{

    public static <T, R>List<R> map(List<T> list,Function<T, R> fun){
        List<R> returnList = new ArrayList<>(list.size());
        for (T e : list) {
            returnList.add(fun.apply(e));
        }
        return returnList
    }

    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(new Employee("老张"),
                new Employee("小李"),
                new Employee("老王"),
                new Employee("小刘"),
                new Employee("小胖"));
        List<String> nameList = map(employees, (employee -> employee.getName()));
        System.out.println(nameList);
        /*
            console:[老张, 小李, 老王, 小刘, 小胖]
        */
    }
}

Predicate<T> 断言型接口

public static <E> List<E> filter(List<E> list, Predicate<E> pred) {
    List<E> retList = new ArrayList<>();
        for (E e : list) {
            if (pred.test(e)) {
                retList.add(e);
            }
        }
    return retList;
}
public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(new Employee("老张"),
                new Employee("小李", 3000.00),
                new Employee("老王", 5000.00),
                new Employee("小刘", 7000.00),
                new Employee("小胖", 10000.00));
        //过滤薪资小于5000的员工
        List<Employee> filter = filter(employees,
                                       employee -> employee.getSalary() > 5000.00);
        for (Employee employee : filter) {
            System.out.println(employee.getName()   ":"   employee.getSalary());
        }
        /*
            console:小刘:7000.0
                    小胖:10000.0
        */
}
package cn.monoy.demos3;@FunctionalInterfacepublic interface FunctionalInterfaceDemo { public void doSomething(); @Override String toString();}

lambda表达式: (参数列表)->{代码}

public interfaceTradePredicate {

格局引用

​ 当要传递给Lambda体的操作,已经有落到实处的主意了,能够行使办法引用!方法引用:使用操作符 ::将方法名和目的或类的名字分隔绝来。如下三种尊敬选用状态

对象 : : 实例方法
类 : : 静态方法
类 : : 实例方法
基本用法
例如:

//静态方法
BinaryOperator<Double> binaryOperator = (x, y) -> Math.pow(x, y);
//等价于
BinaryOperator<Double> binaryOperator = Math::pow;

//实例方法: 类::实例方法
Function<Employee, String> f = (Employee e) -> e.getName();
//等价于
Function<Employee, String> f = Employee::getName;
//---------------------------------------------------------
//对象::实例方法
Employee e = new Employee("小李", 3000.00);
Supplier<String> s = () -> e.getName();
//等价于↓
Supplier<String> s = e::getName;

就此在Java第88中学 Lambda 表达式的功力正是简化函数式接口,你会小心到,我在接口中写了2个Object类的办法toString(),那在Java捌的函数式接口语法中是允许的,在用lambda 表明式的时候Java只会把表明式当成doSomething方法.也正是说在接口中证明Object类中的方法名不会影响那几个接口成为3个函数式接口.

lambda表明式(前边有篇小说说过,不详细表明)

有参数,有重临值的自定义函数式接口

    @FunctionalInterface
    public interface Sumable {
        int sum(int a, int b);
    }

booleantest(Trade trade);

构造方法

​ 与函数式接口相结合,自动与函数式接口中方法兼容。能够把构造器引用赋值给定义的措施,与构造器参数
列表要与接口中架空方法的参数列表壹致!对于构造方法,方法引用的语法是<类名>::new,如Employee::new,如下语句:

Function<String,Employee> f = (name)->new Employee(name);
//等价于↓
Function<String, Employee> f = Employee::new;

选择函数式接口的另一个益处便是能够用lambda表明式赋给1个接口注解的变量.

JDK1.八自此的有个别函数式接口

}

接口中的私下认可方法和静态方法

​ Java八原先,接口里的主意需要全副是虚幻方法,Java8事后允许在接口里定义暗中同意方法静态方法,默许方法应用 default 关键字修饰。

例如:

public interface MyFunction{
  void func();
  //声明一个接口的默认方法
  default void testDefalut(){
    System.out.println("MyFunction 默认方法");
  }
  //声明一个接口的静态方法
  static void testStatic(){
    System.out.println("MyFunction 静态方法");
  }
}

//MyFunctionImpl实现接口MyFunction
public class MyFunctionImpl implements MyFunction {
    @Override
    public void func() {
        System.out.println("实现抽象方法");
    }

    public static void main(String[] args) {
        MyFunction my = new MyFunctionImpl();
        my.func();
        my.testDefalut();
        MyFunction.testStatic();
    }
  /*
            实现抽象方法
            MyFunction 默认方法
            MyFunction 静态方法
  */
}

默许方法的首要优势是提供一种拓展接口的主意,而不损坏现成代码。

package cn.monoy.demos3;public class Main { public static void main(String[] args) {//创建线程 Runnable run = () -> { System.out.println("BlahBlahBlahBlah"); }; Thread thread = new Thread; thread.start();//我自己写的函数式接口 FunctionalInterfaceDemo fi = () -> { System.out.println("BlahBlahBlahBlah"); }; fi.doSomething(); }}

supplier生产数据函数式接口

指标是生育数据.

此时此刻仿佛看不出来有什么用,然则好像和jdk八的Stream流有关.,举个小例子

    package com.wzlove.supplier;

    import java.util.function.Supplier;

    /**
     * 使用supplier函数式接口求数组的最大值
     */
    public class ArrMaxValue {

        public static int getMaxValue(Supplier<Integer> sup){
            return sup.get();
        }

        public static void main(String[] args) {
            // 创建数组
            int[] arr = {100,20,50,30,99,101,-50};

            int maxValue = getMaxValue(()->{
                int max = arr[0];
                for (int i : arr) {
                    if(i > max){
                        max = i;
                    }
                }
                return max;
            });

            System.out.println("数组中的最大值为:"   maxValue);
        }

    }

那正是3个函数式接口。那么什么样去分辨3个接口是还是不是是函数式接口呢?

接口争辩

​ 要是一个父接口提供一个默许方法,而另二个接口也提供了1个有所一样名称和参数列表的办法(不管方法是或不是是默许方法),那么必须覆盖该方法来化解争论

public interface AnotherFunction {
    default void testDefalut() {
        System.out.println("AnotherFunction 默认方法");
    }
}

public class FunctionImpl implements MyFunction,AnotherFunction{
    @Override
    public void func() {
        System.out.println(" FunctionImpl 实现抽象方法");
    }

    @Override
    public void testDefalut() {
         System.out.println(" FunctionImpl 覆盖接口中默认方法解决冲突");
    }
}

​ 假如不掩盖接口中千篇一律的暗中认可方法,那么new MyFunctionImpl().testDefalut();中调用的testDefalut方法到底是哪位接口的testDefalut()方法吧?所以必须在贯彻类中覆盖testDefalut()方法。

从如上代码能够看来,创立线程必须兑现的Runnable接口也是贰个函数式接口.小编把同样的lambda表明式分别赋给了Runnable接口 和笔者要好写的FunctionalInterface德姆o 接口,并不会时有发生什么样错误.个人感到这么的写法能够简化代码层级,使得可读性越来越好.当然,依旧看个人喜好.上面说说极其,在lambda表达式中的代码不可制止要遇见特别管理,假使在lambda表明式中遇见要管理十分.要么直接在表明式中try catch要么就在接口中注解的章程方面抛出,比方

Consumer消费数据函数式接口

这么些主意是用来成本数量的,怎么样消费,消费规则本身定义.

java.util.function.Supplier

package com.wzlove.comsumer;

import java.util.function.Consumer;

/**
 * 使用Consumer函数式接口实现格式化输出
 */
public class ConsumerDemo2 {

    public static void printInfo(String[] strArr, Consumer<String> con1, Consumer<String> con2){

        for (int i = 0; i < strArr.length; i  ) {
            con1.andThen(con2).accept(strArr[i]);
        }

    }

    public static void main(String[] args) {
        String[] strArr = {"迪丽热巴,女","郑爽,女","杨紫,女"};
        printInfo(strArr,(message)->{
            System.out.print("姓名:"   message.split(",")[0]   "。  ");
        },(message)->{
            System.out.println("性别:"   message.split(",")[1]   "。");

        });
    }
}

简轻易单的说:函数式接口正是只定义了1个虚幻方法的接口。例如JavaAPI中的Comparator 和Runnable。

小结

​ 本章中牵线了Java 8中的函数式接口,Java八四大亚湾原子核能发电站心函数式接口,方法的引用,接口的私下认可方法和静态方法。

初稿链接:Java8 新特色 函数式接口 | 火尧

package cn.monoy.demos3;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStream;public class Main { public static void main(String[] args) { FunctionalInterfaceDemo fi = () -> {//直接在代码块中处理 try { InputStream ins = new FileInputStream("test.txt"); } catch (FileNotFoundException e) { e.printStackTrace(); } }; fi.doSomething(); }}

Predicate剖断函数式接口

Predicate 接口中包含3个抽象方法: boolean test(T t) 。用于标准推断的气象

暗中同意方法:

  • default Predicate
  • default Predicate
  • default Predicate

    package com.wzlove.functionalinterface.predicate;

    import java.util.ArrayList;
    import java.util.function.Predicate;

    /**

    • */
      public class PredicateDemo2 {

      /**

      • 检查数组中的元素是不是符合供给,满意要求参加List中并赶回
      • @param arr 需求判别的数组
      • @param pre壹 推断接口壹,推断性别是或不是为女
      • @param pre二 推断接口2,判定姓名长度是或不是超过二
      • @return 集合
        */
        public static ArrayList

      public static void main(String[] args) {
      // 创造数组
      String[] arr = {"迪丽热巴(Dilraba),女","杨洋(英文名:yáng yáng),男","李溪芮(Nikki),女","郑爽女士,女"};

        // 调用方法(Lambda表达式可以简化)
        ArrayList<String> list = checkStar(arr,(str)->{
            return str.split(",")[1].equals("女");
        },(str)->{
            return str.split(",")[0].length() > 2;
        });
      
        // 遍历集合
        for (String elem : list) {
            System.out.print(elem   "   ");
        }
      

      }

    }

public interface Comparator{

作者在接口中给doSomething 加多了throws 注解抛出十一分,则在调用doSomething 时管理此极其

Function类型转换函数式接口

Function 接口中最入眼的画饼充饥方法为: R apply(T t) ,依照类型T的参数获取类型Rubicon的结果。

Function 接口中有二个暗中认可的andThen 方法,用来进展整合操作。

package com.wzlove.functionalinterface.function;

import java.util.function.Function;

/**
 *
 */
public class FunctionDemo2 {

    /**
     * 将String分割,获得第二个元素,将数据转化为int,int数据加100,再将int转化为String
     * @param str    转化的数据
     * @param fun1   String -> String
     * @param fun2   String -> Integer
     * @param fun3   Integer -> String
     * @return       最后的String
     */
    public static String convert(String str,
                              Function<String,String> fun1,
                              Function<String, Integer> fun2,
                              Function<Integer,String> fun3){

        return fun1.andThen(fun2).andThen(fun3).apply(str);

    }

    public static void main(String[] args) {
        String str = convert("迪丽热巴,23",(s)->{
            return s.split(",")[1];
        },(s)->{
            return Integer.parseInt(s)   100;
        },(s)->{
            return String.valueOf(s);
        });
        System.out.println(str);
    }
}

int compare(T o1, T o2);

package cn.monoy.demos3;import java.io.FileInputStream;import java.io.InputStream;public class Main { public static void main(String[] args) { FunctionalInterfaceDemo fi = () -> { InputStream ins = new FileInputStream("test.txt"); }; //在调用时处理异常 也可以选择继续抛出 try { fi.doSomething(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}

}

public interface Runnable{

void run();

}

————————

瞩目:函数式接口是只定义“2个虚无方法”的接口,只定义3个架空方法并代表未有其余措施,前边大家领略,接口里还足以有暗许方法。

————

大家也能够说,加上注解@FunctionalInterface的接口(唯有三个虚无方法的接口),便是三个函数式接口。

——————

有关函数式接口,注意以下几点:

一.假若贰个接口唯有二个空洞方法,那么该接口就是函数式接口。

贰.只要我们在有些接口上声称了@FunctionalInterface注明,那么编写翻译器就能依据函数式接口的概念来要求该接口。

3.例如有些接口唯有多个浮泛方法,但我们并未给该接口评释@FunctionalInterface注明,那么编写翻译器依然会将其视作是函数式接口。

————————————

@FunctionalInterface

public interfaceMyInterface {

本文由澳门新葡亰发布于计算机知识,转载请注明出处:函数式编程初识之函数式接口,Java8函数式编程之

关键词: 函数 Java8函数式编程 Java8 接口 澳门新葡亰889.n

上一篇:Hibernate报错记录,JDBC报错记录

下一篇:没有了

最火资讯