黑马程序员技术交流社区

标题: [石家庄校区]JAVA_函数式接口 [打印本页]

作者: 13333114253    时间: 2018-12-2 15:08
标题: [石家庄校区]JAVA_函数式接口
01-函数式接口
1.自定义函数接口  

               有且仅有一个抽象方法,适用于函数式编程的场景的接口(默认,静态,私有方法,都不算做抽象方法)
               接口中有且只有一个抽象方法
   @FunctionalInterface的作用:

               在接口上使用, 检测当前的接口是否为函数式接口
格式:
修饰符 interface 接口名称 {
    public abstract 返回值类型 方法名称(可选参数信息);
    // 其他非抽象方法内容
}

02-函数式接口
Java中提供的常用 函数式接口:
    Supplier<T>: 生产型函数式接口         获取值  a和b的和, 获取数组最大值, 获取一个Person对象

        java.util.function.Supplier<T>函数式接口: 生产型函数式接口
                      // 抽象方法
                   T get(): 用于获取一个对象或值.
         至于获取什么值, 怎么获取, 需要我们根据应用场景编写Lambda来实现

获取数组最大值
[Java] 纯文本查看 复制代码
public class Test {

    // 方法的作用: 获取最大值  至于怎么获取, 获取什么的最大值, 需要我们传递Lambda表达式来实现
    // 参数的作用: 获取最大值的方式(代码)
    public static int getMax(Supplier<Integer> sup) {
        return sup.get();
    }

    public static void main(String[] args) {
        int[] arr =  {100, 0, -50, 88, 99, 33, -30};

        // 调用方法来获取数组中的最大值, 怎么获取呢? 我们来传递Lambda表达式实现

        // 一开始不熟悉抽象方法的参数和返回值类型, 可以先写匿名内部类, 然后改写为Lambda
        /*int maxValue = getMax(new Supplier<Integer>() {
            @Override
            public Integer get() {
                int max = 0;
                for (int i : arr) {
                    if (i > max) {
                        max = i;
                    }
                }
                return max;
            }
        });*/

        // Lambda方式
        int maxValue = getMax(()->{
            int max = 0;
            for (int i : arr) {
                if (i > max) {
                    max = i;
                }
            }
            return max;
        });

        System.out.println("最大值:" + maxValue);
    }
}

   Consumer<T>: 消费型函数式接口         使用值  给它一个String让他打印, 给它一个对象
          java.util.function.Consumer<T>函数式接口: 消费型函数式接口
           // 抽象方法
          void accept(T t): 用于消费(使用)一个对象或值. 至于怎么消费, 要我们根据应用场景编写Lambda实现
                // 默认方法
         default Consumer<T> andThen(Consumer<? super T> after): 拼接两个Consumer接口的Lambda对象实现连续操作. 谁写前面, 谁先消费


    补充:
      java.lang.StringBuffer类: 可变字符序列, 类似于String, 线程安全效率低
               StringBuffer reverse(): 将StringBuffer内部保存的内容反转
               String toString(): 转换为String

[Java] 纯文本查看 复制代码
public class Test {

        // 定义方法用来消费一个字符串. 参数是 被消费的字符串 和 消费方式1 和 消费方式2
    public static void method(String s, Consumer<String> con1, Consumer<String> con2){
//        con1.accept(s);
//        con2.accept(s);
        
                // 使用andThen简化
        con1.andThen(con2).accept(s);
    }

    public static void main(String[] args) {
                // 传入两种消费方式
        method("Hello",
               (t) -> {
                   System.out.println(t.toUpperCase()); // HELLO
               },
               (t) -> {
                   System.out.println(t.toLowerCase()); // hello
               });
    }
}

Predicate<T>: 条件判断型函数式接口     判断值  判断字符串长度是否大于5
java.util.function.Predicate<T>函数式接口: 条件接口, 用于判断
    // 抽象方法
    boolean test(T t): 判断参数传递的对象. 至于怎么判断, 判断什么, 需要我们编写Lambda表达式实现
    // 默认方法 (用于连接多个判断条件)
    default Predicate<T> and(Predicate<? super T> other): 与 &&
    default Predicate<T> or(Predicate<? super T> other): 或  ||
    default Predicate<T> negate(): 非, 取相反结果   !
    boolean b = 判断方式1.or(判断方式2).and(判断方式3).negate().test("abc")


    Function<T, R>: 转换型函数式接口      转换值  给它一个String转换为

java.util.function.Function<T,R>: 根据一个 T类型的数据 转换为 另一个R类型的数据
    T是 输入(input)的类型
    R是 返回结果(result)的类型
    有进有出, 所以称为"函数Function"
    // 抽象方法
    R apply(T t): 将T转换为R. 至于T和R是什么类型, 以及如何转换, 需要传递Lambda表达式实现
    // 默认方法
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after): 拼接多个Function转换

例:andThen(),apply()
[Java] 纯文本查看 复制代码
public class Test {

    // 方法作用: 按照步骤将字符串转换
    // 参数: 被转换的字符串, 转换方式1, 转换方式2, 转换方式3
    public static int change(String s, Function<String, String> fun1, Function<String, Integer> fun2, Function<Integer, Integer> fun3) {
        return fun1.andThen(fun2).andThen(fun3).apply(s);
    }

    public static void main(String[] args) {
        String str = "赵丽颖,20";

        // 匿名内部类方式
        int num1 = change(
                str,
                new Function<String, String>() {  // 将字符串截取数字年龄部分, 得到字符串
                    @Override
                    public String apply(String s) {
                        return s.split(",")[1];
                    }
                },
                new Function<String, Integer>() {  // 将上一步的字符串转换成为int类型的数字
                    @Override
                    public Integer apply(String s) {
                        return Integer.parseInt(s);
                    }
                },
                new Function<Integer, Integer>() { // 将上一步的int数字累加100, 得到结果int数字
                    @Override
                    public Integer apply(Integer integer) {
                        return integer + 100;
                    }
                }
        );
        System.out.println(num1);

        // Lambda方式
        int num2 = change(
                str,
                s -> s.split(",")[1],
                s -> Integer.parseInt(s),
                i -> i + 100
        );
        System.out.println(num2);
    }
}







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2