Java的函数式接口

1、函数式接口介绍

  函数式接口指的是有且仅有一个抽象方法的接口。 因为在Java 8中,新增了Lambda表达式,Lambda表达式为了实现自己推导方法,所使用的接口必须只能有一个抽象方法。所以,函数式接口就是专为Lambda而产生的特殊接口。

  要定义一个函数式接口,那么该接口只能有一个抽象方法。为了确保只有一个抽象方法,同时也可以告诉别人这是一个抽象方法,我们通常在接口上添加一个注解:@FunctionalInterface。如果这个接口中的定义不满足函数式接口,那么就会报错。但是注解不是必需的,只是写上注解是良好的编程习惯。

/**
 * @author RuiMing Lin
 * @date 2020-03-16 20:38
 */
@FunctionalInterface
public interface MyFunctionalInterface {

    public abstract void method1();      // 抽象方法

    // 虽然函数式接口只能定义一个抽象方法,但是可以定义静态方法、默认方法、私有方法等
    public static void method2(){
        // ...
    }
}

2、函数式接口的使用

定义一个函数式接口:

/**
 * @author RuiMing Lin
 * @date 2020-03-16 20:38
 */
@FunctionalInterface
public interface MyFunctionalInterface {

    public abstract void method1();      // 抽象方法
    
}

定义一个函数式接口的实现类:

/**
 * @author RuiMing Lin
 * @date 2020-03-16 21:56
 */
public class MyFunctionalInterfaceImpl implements MyFunctionalInterface{
    @Override
    public void method1() {
        System.out.println("使用实现类方式实现抽象方法");
    }
}

定义一个测试类:

/**
 * @author RuiMing Lin
 * @date 2020-03-16 21:58
 */
public class Demo1 {
    
    // 定义一个静态方法,调用函数式接口
    public static void print(MyFunctionalInterface myFunctionalInterface){
        myFunctionalInterface.method1();
    }
    
    public static void main(String[] args) {
        // 1.使用方式一:实现类方式
        print(new MyFunctionalInterfaceImpl());
        // 2.使用方式二:使用匿名内部类方式
        print(new MyFunctionalInterface() {
            @Override
            public void method1() {
                System.out.println("使用匿名内部类方式实现抽象方法");
            }
        });
        // 3.使用方式三:使用Lambda表达式
        print(() -> System.out.println("使用Lambda实现抽象方法"));
    }
}

关于Lambda的内容,可以看我另一篇博客的内容:

3、JDK内置的函数式接口

3.1、Supplier接口

  Supplier 接口是java.util.function包下的一个函数式接口,该接口的抽象方法是一个无参的方法:T get() ,用来获取一个泛型参数指定类型的对象数据

使用Supplier接口案例一:

import java.util.function.Supplier;

public class Demo2 { 
	private static String getString(Supplier<String> supplier) { 
		return supplier.get(); 
	}
	public static void main(String[] args) { 
		String str1 = "Hello"; 
		String str2 = "World"; 
		System.out.println(getString(()> str1 + str2)); 
	} 
}

使用Supplier接口案例二:

扫描二维码关注公众号,回复: 10017433 查看本文章
public class Demo3 { 
    public static int getMax(Supplier<Integer> supplier){ 
        return supplier.get(); 
    }
    public static void main(String[] args) { 
        int arr[] = {1,3,100,300,10,30}; 
        int maxNum = getMax(()>{ 
            //计算数组的最大值 
            int max = arr[0]; 
            for(int i : arr){ 
                f(i > max){ 
                    max = i; 
                } 
            }
            return max; 
        }); 
        System.out.println(maxNum); 
    } 
}

3.2、Consumer接口

  Consumer 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定。 它提供了一个抽象方法:void accept(T t) ,作用是使用一个指定泛型的数据。

import java.util.function.Consumer;
/**
 * @author RuiMing Lin
 * @date 2020-03-19 0:14
 */
public class ConsumerTest {
    private static void consumeString(String string, Consumer<String> consumer) {
        consumer.accept(string);
    }

    public static void main(String[] args) {
        String str = "123456789";
        consumeString(str, (s) -> {
            StringBuffer reverse = new StringBuffer(s).reverse();
            System.out.println("reverse = " + reverse);
        });
    }
}

3.3、Predicate接口

  Predicate 接口用来对某种类型的数据进行判断,该接口包含一个抽象方法:boolean test(T t) 。

import java.util.function.Predicate;

/**
 * @author RuiMing Lin
 * @date 2020-03-19 0:26
 */
public class PredicateTest {
    private static void method(String string, Predicate<String> predicate) {
        boolean flag = predicate.test(string);
        if (flag){
            System.out.println("该字符串长度大于10");
        }else {
            System.out.println("该字符串长度不大于10");
        }
    }
    public static void main(String[] args) {
        String string = "abcde123456789";
        method(string,s -> {
            return s.length() > 10;
        });
    }
}

此外,Predicate接口还提供了三个默认方法,and()、or()、negate()

and()使用方式如下:

import java.util.function.Predicate;

/**
 * @author RuiMing Lin
 * @date 2020-03-19 0:26
 */
public class PredicateTest {
    private static void method(String string, Predicate<String> predicate1, Predicate<String> predicate2) {
        boolean flag = predicate1.and(predicate2).test(string);
        if (flag){
            System.out.println("该字符串长度大于10且小于等于20");
        }
    }
    public static void main(String[] args) {
        String string = "abcde123456789";
        method(string,s -> {
            return s.length() > 10;
        },s -> {
            return s.length() <= 20;
        });
    }
}


or()使用方式如下

import java.util.function.Predicate;

/**
 * @author RuiMing Lin
 * @date 2020-03-19 0:26
 */
public class PredicateTest {
    private static void method(String string, Predicate<String> predicate1, Predicate<String> predicate2) {
        boolean flag = predicate1.or(predicate2).test(string);
        if (flag){
            System.out.println("该字符串长度大于10或者小于等于5");
        }
    }
    public static void main(String[] args) {
        String string = "123";
        method(string,s -> {
            return s.length() > 10;
        },s -> {
            return s.length() <= 5;
        });
    }
}


negate()使用方式如下

import java.util.function.Predicate;

/**
 * @author RuiMing Lin
 * @date 2020-03-19 0:26
 */
public class PredicateTest {
    private static void method(String string, Predicate<String> predicate) {
        boolean flag = predicate.negate().test(string);     // 对原结果取非
        if (flag){
            System.out.println("该字符串长度不大于10");
        }
    }
    public static void main(String[] args) {
        String string = "123";
        method(string,s -> {
            return s.length() > 10;
        });
    }
}


3.4、Function接口

  Function<T,R> 接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。 Function 接口提供的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。

import java.util.function.Function;

/**
 * @author RuiMing Lin
 * @date 2020-03-19 0:40
 */
public class FunctionTest {
    private static void method(String numStr,Function<String, Integer> function) {
        // 将数字字符串转化为integer类型
        int num = function.apply(numStr);
        System.out.println(num + 20);
    }
    public static void main(String[] args) {
        method("100",(str) -> {
            return Integer.parseInt(str);
        });
    }
}

有错误的地方敬请指出!觉得写得可以的话麻烦给个赞!欢迎大家评论区或者私信交流!

发布了49 篇原创文章 · 获赞 119 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Orange_minger/article/details/104964342