🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 内建函数式接口 对于方法引用,严格来讲需要定义一个接口,可是不管如何操作,实际上有可能操作的接口只有4种 jdk里面提供了一个包: **java.util.function**,提供有以下四个核心接口 ~~~ 1. 功能性接口(Function): public interface Function<T, R> {public R apply(T t);} | |---此接口需要接收一个参数,并且返回一个处理结果 2. 消费型接口(Consumer): public interface Consumer<T>{public void accept(T t);} | |---此接口只是负责接收数据(引用数据是不需要返回),并且不返回处理结果 |-- 如果方法的参数和返回值全都是Consumer类型,可以做一个操作后再做一个操作,实现组合,就是consumer的默认方法andThen 3. 供给型接口(Supplier): public interface Supplier<T> {public T get();} | |---此接口不接收参数,但是可以返回结果 4. 断言型接口(Predicate): public interface Predicate<T> {public boolean test(T t);} | |---此接口进行判断操作使用 ~~~ 所有在JDK1.8之中由于存在有以上的四个功能型接口,所以一般很少由用户去定义函数式接口 ## 功能性接口Function 用来根据一个类型的数据得到另一个类型的数据,前者成为前置条件,后者成为后置条件 String类有一个方法: `public boolean startsWith(String str)` ~~~ //用内建函数式进行引用 Function<String, Boolean> fun = "#hello"::startsWith; //判断是不是 # 开头 System.out.println(fun.apply("#")); //true ~~~ ~~~ public static void main(String[] args) { method(s -> Integer.parseInt(s)); } public static void method(Function<String, Integer> function) { int num = function.apply("10"); System.out.println(num + 20); } ~~~ **默认接口: andThen** Function接口中有一个默认的andThen方法,用来进行组合操作. 用于先做什么再做什么和consumer中andThen差不多 ~~~ default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } ~~~ ~~~ public static void main(String[] args) { //字符串转为int,再乘以10 method(Integer::parseInt, i -> i *= 10); } public static void method(Function<String, Integer> one, Function<Integer, Integer> two) { int num = one.andThen(two).apply("10"); System.out.println(num + 20); } ~~~ ## 消费型接口Consumer 消费一个数据,消费数据的类型由泛型指定 ~~~ package com.study; import java.util.function.Consumer; public class HelloWorld { public static void main(String[] args) { Consumer<String> cons = System.out::println; cons.accept("hello"); } } ~~~ **默认方法andThen** 如果方法的参数和返回值全都是Consumer类型,可以做一个操作后再做一个操作,实现组合,就是consumer的默认方法andThen jdk中源码 ~~~ default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } ~~~ andThen的语义是一步接一步操作 **注意: java.util.objects的requireNonNull静态方法将会在参数为null时候主动抛出NullPointerException异常,这省去了重复编写if语句和抛出空指针异常的麻烦.** ~~~ public class App { public static void main(String[] args) { String[] arr = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男"}; printInfo(arr, (message) -> { String name = message.split(",")[0]; System.out.println("姓名: " + name); }, (message) -> { String age = message.split(",")[1]; System.out.println("年龄: " + age); }); } public static void printInfo(String[] arr, Consumer<String> con1, Consumer<String> con2) { //遍历字符串 for (String message : arr) { //使用andThen方法连接两个Consumer接口,消费字符串 con1.andThen(con2).accept(message); } } } ~~~ ## 供给型接口Suppiler 对外提供一个符合泛型类型对象数据. 使用String类的toUpperCase()方法: `public String toUpperCase();` ~~~ package com.study; import java.util.function.Supplier; public class HelloWorld { public static void main(String[] args) { Supplier<String> supplier = "helllo" :: toUpperCase; System.out.println(supplier.get()); //HELLLO } } ~~~ ## 断言型接口Predicate 有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果.就可以用这个. String类里面有一个equalsIgnoreCase()方法 ~~~ package com.study; import java.util.function.Predicate; public class HelloWorld { public static void main(String[] args) { Predicate<String> pre = "hello"::equalsIgnoreCase; System.out.println(pre.test("Hello")); } } ~~~ ~~~ public static void main(String[] args) { String s = "abcdef"; boolean b = checkString(s, (str) -> str.length() > 5); System.out.println(b); } public static boolean checkString(String s, Predicate<String> pre) { return pre.test(s); } ~~~ **默认方法: and** 既然是条件判断,就会存在与,或,非三种常见的逻辑关系.其中将两个Predicate条件使用"与"逻辑连接起来实现"并且"的效果时,可以使用and ~~~ default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); ~~~ ~~~ public static void main(String[] args) { method(s -> s.contains("h"), s -> s.contains("w")); } private static void method(Predicate<String> one, Predicate<String> two) { boolean bool = one.and(two).test("hello world"); System.out.println("字符串符合要求吗: " + bool); } ~~~ **默认方法: or** 与and的"与"类似,默认方法or实现逻辑关系中的"或".jdk源码为: ~~~ default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } ~~~ 如果希望实现逻辑字符串包含h或者包含w,那么代码只要改为or就可以 ~~~ public static void main(String[] args) { method(s -> s.contains("h"), s -> s.contains("w")); } private static void method(Predicate<String> one, Predicate<String> two) { boolean bool = one.or(two).test("hello world"); System.out.println("字符串符合要求吗: " + bool); } ~~~ **默认方法: negate** 取反 ~~~ default Predicate<T> negate() { return (t) -> !test(t); } ~~~ ~~~ public static void main(String[] args) { String s = "abc"; boolean b = checkString(s, (String str) -> { //判断是否大于5 return str.length() > 5; }); System.out.println(b); } public static boolean checkString(String s, Predicate<String> pre) { //取反 return !pre.test(s); } ~~~ ~~~ public static void main(String[] args) { Predicate predicate = (i) -> i > 5 ? true : false; method(predicate.negate()); } public static void method(Predicate one) { boolean test = one.test(10); System.out.println(test); } ~~~ 除了这几个还有其他和他类似的接口在jdk包下 # 其他接口 ![](https://img.kancloud.cn/66/68/66684f5cc03f11799494c580fdd147a8_1602x936.png)