Skip to content

[!quote] 函数式接口 函数式接口 是有且仅有一个抽象方法的接口,函数式接口完全就是为了 Lambda 表达式而打造的,它的概念就是 Lambda 表达式的使用前提

  • 使用 @FunctionalInterface 让编译器检查该接口是否符合函数式接口规范

函数式接口用作局部变量

java
@FunctionalInterface               //这是一个注解,告诉别人这是函数式接口。
public interface MyInterface {     //加上注解之后,再在该接口中添加方法会报错
    void show();  
}
java
public class Demo {  
    public static void main(String[] args) {  
        MyInterface mif = () -> System.out.println("函数式接口");  
        mif.show();  
    }                     //其实Lambda表达式代表的还是MyInterface的一个实现类对象
}


函数式接口

函数式接口作为方法参数

上述已经写了很多了

函数式接口作为方法的返回值

java
public class ComparatorDemo {  
    public static void main(String[] args) {  
        TreeSet<String> ts = new TreeSet<String>(getComparator());    //传入这个比较器
  
        String s1 = "刘德华";  
        String s2 = "黎明";  
        String s3 = "欧阳娜娜";  
  
        ts.add(s1);  
        ts.add(s2);  
        ts.add(s3);  
  
        for (String s : ts) {  
            System.out.println(s);  
        }  
    }  
  
    public static Comparator<String> getComparator() {  
//        Comparator<String> cp = new Comparator<String>() {  
//            @Override  
//            public int compare(String s1, String s2) {             //匿名内部类
//                return s1.length() - s2.length();  
//            }  
//        };  
//        return cp;  
  
        Comparator<String> cp = (String s1, String s2) -> {  
            return s1.length() - s2.length();  
        };  
  
        return cp;  
    }  
}


黎明
刘德华
欧阳娜娜

❤️ 常用的函数式接口

💛 Supplier

[!quote] Supplier Supplier 是一个生产型接口,get() 方法不用参数,而且还返回(生产)一个泛型

@FunctionalInterface 
public interface Supplier\<T>
  • T get() 返回一个泛型 T
java
public class SupplierDemo {  
    public static void main(String[] args) {  
        int arr[] = {4, 2, 55, 33, 88};                  //定义数组
  
        int Max = getMax(new Supplier<Integer>() {       //接收最大值
            @Override  
            public Integer get() {                  //重写get()方法
                int max = arr[0];  
  
                for (int i = 1; i < arr.length; i++) {  
                    if (arr[i] > max) {  
                        max = arr[i];  
                    }  
                }  
                return max;  
            }  
        });  
        System.out.println(Max);                    //输出数组的最大值
    }  
  
    public static int getMax(Supplier<Integer> sup) {  
        return sup.get();  
    }  
}


88

💛 Consumer

[!quote] Consumer Consumer 是一个消费型接口,接收一个参数,做一系列操作,无返回值

@FunctionalInterface 
public interface Consumer\<T>
  • void accept(T t) 对给定的参数 T 进行操作
java
public class ConsumerDemo {  
    public static void main(String[] args) {  
        OpString("吴彦祖", (String s) -> System.out.println(s.length()));  
    }  
  
    public static void OpString(String s, Consumer<String> con) {  
        con.accept(s);  
    }  
}


3

💛 Predicate

[!quote] Predicate Predicate 是一个评估型接口,接收一个参数进行评估,返回一个 boolean

@FunctionalInterface 
public interface Predicate\<T>
  • boolean test(T t) 接收泛型,评估后,返回 boolean 值
  • default Predicate<\T> negate() 返回一个逻辑的否定(逻辑非)
  • default Predicate<\T> and(Predicate other) 返回一个组合判断(逻辑与)
  • default Predicate<\T> or(Predicate other) 返回一个组合判断(逻辑或)

test()

java
public static void main(String[] args) {  
	Boolean b = CheckString("吴彦祖", (String s) -> {  
		return s.equals("吴彦祖");  
	});  
  
	System.out.println(b);  
}  
  
public static boolean CheckString(String s, Predicate<String> pre) {  
	return pre.test(s);         
}


true

negate()

java
public static void main(String[] args) {  
	Boolean b = CheckString("吴彦祖", (String s) -> {  
		return s.equals("吴彦祖");  
	});  
  
	System.out.println(b);  
}  
  
public static boolean CheckString(String s, Predicate<String> pre) {  
	return pre.negate().test(s);              //先对pre进行negate操作,然后调用test()
}


false

[!faq] 为什么不直接 return !pre.test(s),而是 return pre.negate().test(s)? 结果虽然相同但是理念不同

前者表达的是,返回一个 predicate 对象调用 test 方法之后结果的非 后者表达的是,返回一个 predicate 对象的逻辑非后,再调用 test 方法的结果

and(),or()

java
public static void main(String[] args) {  
	Boolean b = CheckString("吴彦祖", (String s) -> {  
		return s.equals("吴彦祖");  
	}, (String s) -> {  
		return s.equals("陈冠希");  
	});  

	System.out.println(b);  
}  

public static boolean CheckString(String s, Predicate<String> pre1, Predicate<String> pre2)     {  
	//boolean b1 = pre1.test(s);  
	//boolean b2 = pre2.test(s);              //可用这三条语句代替,但是表意不同
	//return b3 = b1 && b2;  
	return pre1.and(pre2).test(s);  
}


false

💛 Function

[!quote] Function Function 是一个转换型接口,接收一个参数将其转换为另一个参数

@FunctionalInterface
public interface Function\<T,R>

  • R apply(T t)
  • default<V> Function<T,V> andThen(Function after)
java
public class FunctionDemo {  
    public static void main(String[] args) {  
        convert("100", (String s) -> {  
            return Integer.parseInt(s);  
        });  
    }  
  
    public static void convert(String s, Function<String, Integer> fun) {  
        int i = fun.apply(s);  
        System.out.println(i);  
    }  
}


100

💛 Runnable

Runnable 函数式接口没有入参,没有返回值,只是执行

java
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

闭包

[!quote] 闭包 闭包 就是函数在定义时,“记住”了它自己所在的作用域中的变量 【counter 函数记住了 createCounter 里的 count 变量】

java
public static void main(String[] args) {
	Supplier<Integer> counter = createCounter();

	// 每次调用,闭包都会记住 count 的状态
	System.out.println(counter.get()); // 输出 1
	System.out.println(counter.get()); // 输出 2
	System.out.println(counter.get()); // 输出 3
}

private static Supplier<Integer> createCounter() {
	// 使用数组来保存状态(因为外部变量需要是 effectively final)
	int[] count = {0}; 
	return () -> {
		count[0]++;
		return count[0];
	};
}