有且只有一个抽象方法的接口。

 

@FunctionalInterface						// 注解:检测接口是否是一个函数式接口
修饰符 interface 接口名称 {
	public abstract void method();			// public abstract 还是推荐加上
}

函数式接口通常与Lambda表达式配合使用
 
下面给出几个常用的函数式接口:

Supplier—get——生产工厂

Consumer—accept——消费,即使用

Predicate—test——判断

Function—apply——类型转换

 

 
Supplier——生产工厂

Supplier接口被称为生产型接口:指定泛型是什么类型,接口的get()方法就会生产什么样的类型的数据
具体生成一个怎样的数据?就由之后传入的Lambda表达式决定吧!

import java.util.function.Supplier;

public class Demo {

    // 这里的语义是:生成一个字符串,生成怎样的字符串呢?这由Lambda表达式决定
    private static String getString(Supplier<String> sup) {
        return sup.get();
    }

    public static void main(String[] args) {
        String s = getString(()->"Loli");
        System.out.println(s);
    }
}
// 练习:求数组元素最大值
public class Prac {	

	// 生成怎样的数字呢?这由Lambda表达式决定
    private static Integer getMax(Supplier<Integer> sup){
        return sup.get();									
    }

    public static void main(String[] args) {
        int[] arr = {2, 5, 12, 9};
        int max = getMax(()->{
            int maxNum = arr[0];
            for(int n : arr){
                maxNum = Math.max(maxNum, n);
            }
            return maxNum;
        });
        System.out.println("数组的最大值为" + max);
    }
}

 

Consumer——消费,即使用

与生产工厂Supplier相反,Consumer用来消费,即使用一个数据
具体怎样消费、怎样使用这个数据呢?就由之后传入的Lambda表达式决定吧!

import java.util.function.Consumer;

public class Demo01 {

    public static void consume(String s, Consumer<String> con){
        con.accept(s);
    }

    public static void main(String[] args) {
    	// 使用方式:打印
        consume("Loli", (s)->{
            System.out.println(s);
        });

		// 消费方式:反转后输出
        consume("Loli", (s)->{
            String s2 = new StringBuilder(s).reverse().toString();
            System.out.println(s2);
        });
    }
}


/* 
Consumer接口的andThen默认方法:  将两个Consumer组合在一起
 */
public class Demo02 {

    public static void consume(String s, Consumer<String> con1, Consumer<String> con2) {
        con1.andThen(con2).accept(s);
        // 完全等价于
        // con1.accept(s);
        // con2.accept(s);
    }

    public static void main(String[] args) {
        consume("loli", (s)->{
            System.out.println(s.toUpperCase());
        }, (s)->{
            System.out.println(s.toLowerCase());
        });
    }
}
// 练习:格式化输出数组(按照【姓名】和【年龄】)
public class Prac {

    public static void printer(Consumer<String> con1, Consumer<String> con2, String[] arr){
        for(String s : arr){
            con1.andThen(con2).accept(s);
        }
    }

    public static void main(String[] args) {
        String[] arr = {"Alice,12", "Chino,10", "Cocoa,9"};
        printer((s)->{												
            System.out.println("姓名:" + s.split(",")[0] + ";");
        }, (s)->{
            System.out.println("年龄:" + s.split(",")[1] + ".\n");
        }, arr);
    }
}

 

Predicate——判断

对某种数据类型的数据进行判断,返回一个布尔值
具体根据什么判断呢?就由之后传入的Lambda表达式决定吧!

import java.util.function.Predicate;

public class Demo01 {

    public static boolean judge(String s, Predicate<String> pre){
        return pre.test(s);
    }

    public static void main(String[] args) {
        boolean bool = judge("loli", (s)-> s.length() > 5);
        System.out.println(bool);
    }
}


/*
三个方法————与、或、非
*/
public class Demo02 {

    // 逻辑表达式
    public static boolean judge1(String s, Predicate<String> pre1, Predicate<String> pre2) {
        return pre1.and(pre2).test(s);
        // 完全等价于return pre1.test(s) && pre2.test(s);
    }

    public static boolean judge2(String s, Predicate<String> pre1, Predicate<String> pre2){
        return pre1.or(pre2).test(s);
        // 完全等价于return pre1.test(s) || pre2.test(s);
    }

    public static boolean judge3(String s, Predicate<String> pre){
        return pre.negate().test(s);
        // return ! pre.test(s);
    }

    public static void main(String[] args) {
        boolean bool1 = judge1("loli", (s) -> s.length() > 3, (s) -> s.contains("a"));
        boolean bool2 = judge2("loli", (s) -> s.length() > 3, (s) -> s.contains("a"));
        boolean bool3 = judge3("loli", (s) -> s.length() > 3);
    }
}
// 练习:数组筛选功能(【名字】长度等于5,【年龄】大于等于10)
public class Prac {

    public static String[] filter(String[] arr, Predicate<String> pre1, Predicate<String> pre2) {
        List<String> list = new ArrayList<>();
        for (String s : arr) {
            if (pre1.and(pre2).test(s)) {
                list.add(s);
            }
        }
        return list.toArray(new String[list.size()]);
    }


    public static void main(String[] args) {
        String[] arr = {"Alice,12", "Chino,10", "Cocoa,9"};
        String[] res = filter(arr, (s) -> s.split(",")[0].length() == 5, (s) -> Integer.valueOf(s.split(",")[1]) >= 10);
        System.out.println(Arrays.toString(res));
    }
}

 

Function——类型转换

对某种数据类型转化成另一种数据类型(甚至可以转化为原先的类型)
转换的过程是怎样的呢?就由之后传入的Lambda表达式决定吧!

import java.util.function.Function;

public class Demo {

    public static int trans(String s, Function<String, Integer> fun){
        return fun.apply(s);
    }

    public static void main(String[] args) {
        int n = trans("233", (s)->Integer.parseInt(s));
        System.out.println(n);
    }
}

/*
同样拥有andThen方法
*/
public class Demo02 {

	// 将字符串转化成整形后+10,再转化回字符串
    public static String trans(String s, Function<String, Integer> fun1, Function<Integer, String> fun2) {
        return fun1.andThen(fun2).apply(s);
    }

    public static void main(String[] args) {
        String str = trans("12", (s) -> Integer.valueOf(s) + 10, (n) -> String.valueOf(n));
        System.out.println(str);
    }
}
// 练习————不练了不练了,和上面一样的套路

 

 

 

 

 

 

 

 

 

 

 
 

End

By a Lolicon