JavaSE——Java8之四大函数式接口

常用的函数式接口:

1、Supplier接口:java.util.function.Supplier< T >

     java.util.function.Supplier<T> 接口仅包含一个无参的方法: T get()  
     用来获取一个泛型参数指定类型的对象数据。
     Suppelier<T> 接口被称之为生产型接口,指定接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据

代码演示:

import java.util.function.Supplier;

public class SupplierDemo {
    //接口指定泛型String类,方法get返回值就是String类型
    public static String getString(Supplier<String> supplier){
         return supplier.get();
    }

    public static void main(String[] args) {
        String str = getString(() -> {
            return "hello java";
        });
        System.out.println(str);
    }
}

练习: 求数组中的最大值,使用Supplier接口作为方法参数类型,通过Lambda表达式求出int数组中的最大值。

代码演示:

import java.util.function.Supplier;

public class SupplierTest {
    public static int getMax(Supplier<Integer> supplier){
        return supplier.get();
    }
    public static void main(String[] args) {
        int[] arr = {-1, -9, 20, 23, 54, -30, -78, 996};
        //方法的参数是一个函数式接口,使用Lambda表达式获取最大值
        int maxValue = getMax(() -> {
            //获取数组的最大值
            int max = arr[0];
            for (int i = 1; i < arr.length; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                }
            }
            return max;
        });
        System.out.println("maxValue=" + maxvalue);
    }
}

执行结果:
在这里插入图片描述

2、Consumer接口:java.util.funcation.Consumer< T >

   java.util.funcation.Consumer<T> 接口正好和接口Supplier相反;
   它是负责消费一个数据,数据类型由泛型决定;

Consumer接口中的抽象方法void accept(T t) , 意思是消费一个指定的反泛型数据。

代码演示:

import java.util.function.Consumer;

public class ConsumerDemo {
    /*
        定义一个方法,方法的参数1传递一个字符串的姓名
        方法的参数2传递Consumer接口,泛型使用String类型
        使用Consumer接口消费字符串姓名
     */
    public static  void consumerStr(String name,Consumer<String> consumer){
        //Consumer接口中的方法accept意思是消费一个指定的泛型数据
        consumer.accept(name);
    }

    public static void main(String[] args) {
        consumerStr("Lebron",(String name)->{
            //对传入的数据进行消费
            StringBuffer reverse = new StringBuffer(name).reverse();
            System.out.println(reverse);
        });
    }
}

执行结果:
在这里插入图片描述

Consumer接口中的默认方法:andThen

   Consumer接口中的默认方法:andThen
   如果一个方法的参数和返回值类型都是Consumer类型,那么就可以实现效果:
   在消费数据的时候,首先做一个操作,然后在做一个操作,实现组合。

代码演示:

import java.util.function.Consumer;

/**
 * Consumer接口中的方法andThen
 * 作用:把两个Consumer接口组合到一起,再对数据进行消费
 * 比如:
 * Consumer con1
 * Consumer con2
 * String s
 * con1.accept(s)
 * con2.accept(s)
 * 这段代码使用andThen方法优化,将两个Consumer组合到一起,
 * 再对数据进行消费
 * con1.andThen(con2).accept();
 */
public class ConsumerDemo1 {
    public static void method(String str, Consumer<String> con1, Consumer<String> con2) {
        /*不使用andThen
        con1.accept(str);
        con2.accept(str);*/
        //使用andThen
        con1.andThen(con2).accept(str);
    }

    public static void main(String[] args) {
        method("hello JavA",
                (t)->{
                    System.out.println(t.toUpperCase());
                },
                (t)->{
                    System.out.println(t.toLowerCase());
                }
        );
    }
}

执行结果:
在这里插入图片描述
练习:

      一个字符串数组中存有多条信息,按照格式 :姓名:XX ,年龄:xx 的格式将信息打印出来。
       要求将打印姓名的动作作为第一个Consumer接口中的 Lambda 实例。
       将打印性别的动作作为第二个Consumer接口的Lambda实例。
       将两个Consumer接口按照顺序拼接到一起

代码演示:

import java.util.function.Consumer;

public class ConsumerTest {
    /**
     * 定义方法对字符串进行消费
     *
     * @param arr  字符串数组
     * @param con1 第一个Consumer接口
     * @param con2 第二个Consumer接口
     */
    public static void printInfo(String[] arr, Consumer<String> con1, Consumer<String> con2) {
        for (String msg : arr) {
            con1.andThen(con2).accept(msg);
        }
    }

    public static void main(String[] args) {
        String[] infoArr = {"Kobe,39", "Lebron,35", "Durant,32", "Curry,31"};
        printInfo(infoArr,
                (msg) -> {
                    //对姓名进行切割打印
                    String name = msg.split(",")[0];
                    System.out.print("姓名:" + name+" ");
                },
                (msg) -> {
                    //对性别进行打印
                    String age = msg.split(",")[1];
                    System.out.println("年龄:" + age);
                });
    }
}

执行结果:
在这里插入图片描述

3、Predicate接口:java.util.function.Predicate< T >

抽象方法:test< T t > 方法:

   Predicate接口中的抽象方法:boolean test<T t> 用于判断传入的参数t是否为定义的泛型类型。

代码演示:

/**
 * 方法test用来检测指定的数据是否符合泛型
 * 返回值 true:符合 false:不符合
 */
public class PredicateDemo {
    /**
     * @param string 要检测的数据
     * @param predicate 用于检测的接口,泛型是String类型
     * @return 返回值true或false
     */
    public static boolean checkStr(String string, Predicate<String> predicate){
        return predicate.test(string);
    }

    public static void main(String[] args) {
        boolean b = checkStr("hello java", (String str) -> {
            //判断字符串长度是否大于5
            return str.length() > 5;
        });
        System.out.println(b);
    }
}

默认方法:and

     Predicate 中的方法 and 用于判断条件,表示并且关系,可以用于连接两个判断条件

代码演示:

import java.util.function.Predicate;

/**
 * 需求:传递一个字符串
 * 有两个条件
 * 1:判断字符串的长度是否大于5;
 * 2:判断字符串是否以a字符开头
 */
public class PredicateDemo1 {
    /**
     * 判断字符串的方法
     *
     * @param str  指定的字符串
     * @param pre1 传入的第一个接口
     * @param pre2 传入的第一个接口
     * @return boolean 类型的返回值
     */
    public static boolean checkStr(String str, Predicate<String> pre1, Predicate<String> pre2) {
        return pre1.and(pre2).test(str);
    }

    public static void main(String[] args) {
        String str = "abcdefgh";
        boolean b = checkStr(str, (String s) -> {
            return s.length() > 5;
        }, (String s) -> {
            return s.startsWith("a");
        });
        System.out.println(b);
    }
}

默认方法 or 和 negate

    Predicate 接口中的方法or: 或运算,用于两个来判断条件,用法和and类似;
    negate : 返回一个表示该谓词的逻辑否定的谓词,其实就是取反运算。

练习: 数组中有多条" 姓名+ 年龄 " 的信息,通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,

     筛选条件:1、名字长度大于4;2、年龄大于30。

代码演示:

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

/*
数组中有多条" 姓名+ 年龄 " 的信息,
通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,
 筛选条件:1、名字长度大于4;2、年龄大于30。
*/
public class PredicateTest {
    /**
     * 定义方法筛选符合名字和年龄符合要求的信息
     *
     * @param infoArr 信息数组
     * @param pre1    用于筛选第一个条件的接口参数
     * @param pre2    用于筛选第二个条件的接口参数
     * @return 返回一个包含符合条件的集合
     */
    public static ArrayList<String> filterStr(String[] infoArr, Predicate<String> pre1,
                                              Predicate<String> pre2) {
        ArrayList<String> list = new ArrayList<>();
        for (String string : infoArr) {
            boolean b = pre1.and(pre2).test(string);
            //如果b==true
            if (b) {
                list.add(string);
            }
        }
        return list;
    }

    public static void main(String[] args) {
        String[] infoArr = new String[]{"Lebron,35", "Curry,29", "Durant,32", "Harden,28", "paul,34"};
        ArrayList<String> list = filterStr(infoArr,
                (String str) -> {
                    return str.split(",")[0].length() >= 5;
                },
                (String str) -> {
                    return str.split(",")[1].startsWith("3");
                });
        for (String s : list) {
            System.out.println(s);
        }
    }
}

执行结果:
在这里插入图片描述

4、Function 接口

    java.util.function.Function< T, R > 
    这个接口用来根据一个类型的数据得到另一个类型的数据,
    前面的泛型称之为前置条件,后面的泛型称之为后置条件。

默认方法:R apply(T t),根据类型参数 T 获取类型 R 的结果

代码演示:

import java.util.function.Function;

/**
 * Function接口中的方法:  R apply(T t)
 * 根据参数T得到类型为R的结果
 * 使用场景:
 * 比如将字符串类型的整数,转换为Integer类型的整数
 */
public class FunctionDemo1 {
    /**
     * 定义方法把类型为String类型的整数转换为Integer
     *
     * @param str      传入的字符串整数
     * @param function 接口Function 泛型分别为String和Integer
     * @return 返回转换后的Integer整数
     */
    public static void changeStr(String str, Function<String, Integer> function) {
        Integer integer = function.apply(str);
        System.out.println(integer);
    }

    public static void main(String[] args) {
        String str = new String("11235813");
        changeStr(str, (String string) -> {
            return Integer.parseInt(string);
        });
        //优化Lambda表达式
        changeStr(str, string -> Integer.parseInt(string));
    }
}

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

需求:把String类型的 “123” 转换为Integer,再把转换后的数据加13;再把增加后的Integer数据转换为String类型

代码演示:

import java.util.function.Function;

public class FunctionTest {
    /**
     * 把String转换为Integer,再把Integer转换为String的方法
     *
     * @param str  字符串整数
     * @param fun1 把String转换为Integer的接口
     * @param fun2 把Integer转换为String的接口
     */
    public static void change(String str, Function<String, Integer> fun1, Function<Integer, String> fun2) {
        String s = fun1.andThen(fun2).apply(str);
        System.out.println(s);
    }

    public static void main(String[] args) {
        String string = "1234";
        change(string,
                (String s) -> {
                    return Integer.parseInt(s) + 13;
                },
                (Integer i) -> {
                    return String.valueOf(i);
                });
    }
}

执行结果:
在这里插入图片描述

以上就是几种常用的函数式接口。

发布了58 篇原创文章 · 获赞 7 · 访问量 2277

猜你喜欢

转载自blog.csdn.net/weixin_42492089/article/details/103493550
今日推荐