Java8新特性函数式接口是使用注解@FunctionalInterface标识,并且只包含一个抽象方法的接口是函数式接口。包含Supplier供给型接口、Consumer消费型接口、Predicate断定型接口、Function函数型接口。以下分别详细介绍这4大类函数式接口。

函数式接口的分类(四大核心函数式接口)

1.Supplier供给型接口

简介

java.util.function.Supplier<T> 接口定义了一个 get 的抽象方法,它没有参数,返回一个泛型T的对象,其函数描述符为 () -> T,如果不接受入参,直接为我们生产一个指定的结果,那么就可以用Supplier,这类似于一个工厂方法,通常称为功能型接口

Supplier不接受参数、只返回数据

image-20230421064410206

示例

外部配置文件Properties文件读取

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
     * Supplier使用示例
     * 读取外部配置文件
     *
     * @param fileName 文件名
     * @return util.Properties
     * @author gcoder
     * @date 2023-04-21
     */
    public static Properties readFile(String fileName) {
        Supplier<Properties> supplier = () ->{
            try (InputStream is = Test1.class.getClassLoader().getResourceAsStream(fileName);) {
                Properties properties = new Properties();
                properties.load(is);
                return properties;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        };
        return supplier.get();
    }

JAVA

作为函数参数来使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
/**
     * 作为函数参数使用
     *
     * @param supplier supplier
     * @author gcoder
     * @date 2023-04-21
     */
    public void start(Supplier<String> supplier) {
        String s = supplier.get();
        System.out.println(s);
    }

JAVA

2.Consumer消费型接口

简介

java.util.function.Consumer<T> 接口定义了一个名叫 accept 的抽象方法,它接受泛型 T,没有返回值(void)。如果需要访问类型 T 的对象,并对其执行某些操作,可以使用这个接口,通常称为消费型接口

Consumer只接受一个参数、没有返回值

image-20230421065442006

示例

消费字符串

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
        acceptString("gcoder",s -> {
            String[] split = s.split("");
            String join = String.join("-", split);
            System.out.println("join = " + join);
        });
    }

    /**
     * 消费字符串
     *
     * @param str      str
     * @param consumer consumer
     * @author gcoder
     * @date 2023-04-21
     */
    public static void acceptString(String str, Consumer<String> consumer) {
        consumer.accept(str);
    }

JAVA

连续消费字符串

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static void main(String[] args) {
        acceptString2("gcoder", s -> {
                    String[] split = s.split("");
                    String join = String.join("-", split);
                    System.out.println("join = " + join);
                }, s -> {
                    System.out.println(s + "第二次消费");
                }
        );
    }

    /**
     * 消费字符串
     *
     * @param str       str
     * @param consumer1 consumer1
     * @param consumer2 consumer2
     * @author gcoder
     * @date 2023-04-21
     */
    public static void acceptString2(String str, Consumer<String> consumer1, Consumer<String> consumer2) {
        consumer1.andThen(consumer2).accept(str);
    }

JAVA

3.Predicate断定型接口

简介

java.util.function.Predicate接口,是一个断定型接口,用于对指定类型的数据进行判断,从而得到一个判断结果(boolean类型的值)。

image-20230421100428546

示例
  1. boolean test(T t) ,用于条件判断

    image-20230421100641244

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    public static void main(String[] args) {
            boolean test = checkStr("test", s -> s.length() == 4);
            System.out.println("test = " + test);
        }
    
        /**
         * 判断字符串
         *
         * @param str str
         * @param predicate predicate
         * @return boolean
         * @author gcoder
         * @date 2023-04-21
         */
        public static boolean checkStr(String str,Predicate<String> predicate) {
           return predicate.test(str);
        }
    
    JAVA
    
  2. Predicate<T> and(Predicate<? super T> other),用于将两个Prediccate进行逻辑判断

    image-20230421125731774

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    public static void main(String[] args) {
            boolean test = checkStr("test", s -> s.length() == 4, s -> s.equals("qwer"));
            System.out.println("test = " + test);
        }
    
        /**
         * 多个条件判断字符串
         *
         * @param str str
         * @param p1  predicate
         * @param p2  predicate
         * @return boolean
         * @author gcoder
         * @date 2023-04-21
         */
        public static boolean checkStr(String str, Predicate<String> p1, Predicate<String> p2) {
            return p1.and(p2).test(str);
        }
    
    JAVA
    
  3. Predicate<T> negate(),用于取反判断

    image-20230421143508045

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    public static void main(String[] args) {
            boolean test = checkStr2("test", s -> s.length() != 4);
            System.out.println("test = " + test);
        }
    
        /**
         * 取反判断字符串
         *
         * @param str str
         * @param p1  predicate
         * @return boolean
         * @author gcoder
         * @date 2023-04-21
         */
        public static boolean checkStr2(String str, Predicate<String> p1) {
            return p1.negate().test(str);
        }
    
    JAVA
    
  4. Predicate<T> or(Predicate<? super T> other),用于两个Predicate的逻辑”或“判断

    image-20230421145331669

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    public static void main(String[] args) {
            boolean test = checkStr2("test", s -> s.length() == 4,s -> s.contains("z"));
            System.out.println("test = " + test);
        }
    
        /**
         * 多个条件判断字符串
         *
         * @param str str
         * @param p1  predicate
         * @param p2  predicate
         * @return boolean
         * @author gcoder
         * @date 2023-04-21
         */
        public static boolean checkStr2(String str, Predicate<String> p1, Predicate<String> p2) {
            return p1.or(p2).test(str);
        }
    
    JAVA
    

4.Function函数型接口

简介

java.util.function.Function接口,是一个函数型接口,用来根据一个类型的数据得到另外一个类型的数据

image-20230421145837347

image-20230421145837347

示例
  1. 抽象方法R apply(T t),根据类型T的参数获取类型R的结果

    image-20230421145933644

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    public static void main(String[] args) {
            Integer integer = applyMethod("12345", Integer::parseInt);
            System.out.println("integer = " + integer);
        }
    
        /**
         * 字符串整数的转换
         *
         * @param str      str
         * @param function function
         * @return Integer
         * @author gaohuiwu
         * @date 2023-04-21
         */
        public static Integer applyMethod(String str, Function<String, Integer> function) {
            return function.apply(str);
        }
    
    JAVA
    
  2. <V> Function<V, R> compose(Function<? super V, ? extends T> before),获取apply的function

    image-20230421151122322

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    public static void main(String[] args) {
            String s1 = applyMethod("12345", s -> s + "777", s -> s + "666");
            System.out.println("s1 = " + s1);
        }
    
        /**
         * 先执行前置函数
         *
         * @param str str
         * @param f1  function
         * @param f2  function
         * @return Integer
         * @author gaohuiwu
         * @date 2023-04-21
         */
        public static String applyMethod(String str, Function<String, String> f1, Function<String, String> f2) {
            return f1.compose(f2).apply(str);
        }
    
    JAVA
    
  3. <V> Function<T, V> andThen(Function<? super R, ? extends V> after),用来进行组合操作,即:”先做什么,再做什么“的场景

    image-20230421154110020

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    public static void main(String[] args) {
            String s1 = applyMethod2("12345", s -> s + "777", s -> s + "666");
            System.out.println("s1 = " + s1);
        }
    
        /**
         * 执行后置函数
         *
         * @param str str
         * @param f1  function
         * @param f2  function
         * @return Integer
         * @author gaohuiwu
         * @date 2023-04-21
         */
        public static String applyMethod2(String str, Function<String, String> f1, Function<String, String> f2) {
            return f1.andThen(f2).apply(str);
        }
    
    JAVA
    

以上就是四大核心函数式接口了,在我们的代码开发过程中,实际上就可以借这些代码来简化我们的代码,除去复杂的多重if判断的场景等。函数式编程是比较自由的,并且它的灵活性很高,也够独立,所以善用函数式编程会让我们的编码更加的简洁美好,可读性更高。