常用函数式接口

Lambda表达式

回顾Lambda表达式,当接口或抽象类只有一个抽象方法时可以使用Lambda表达式实现方法,精简语句。
线程的创建:

public class Demo01Runnable {
    public static void startThread(Runnable run) {
        new Thread(run).start();
    }

    public static void main(String[] args) {
        startThread(() -> System.out.println(Thread.currentThread().getName() + "线程启动了"));
    }
}

在排序中自定义比较规则:

public class Demo02Comparator {

    public static Comparator<String> getComparator(){
        return (o1, o2) -> o2.length() - o1.length();
    }

    public static void main(String[] args) {
        String[] arr = {"aa", "bbb", "ddd"};
        Arrays.sort(arr, getComparator());
        System.out.println(Arrays.toString(arr));
    }
}

函数式接口

只有一个抽象方法的接口称为函数式接口,可以用注解@FunctionalInterface显式表明这是一个函数式接口:

@FunctionalInterface    //检测接口是否函数式接口
public interface MyFunctionalInterface {
    public abstract void method();
    //void method2();
}

在某些场景下使用函数式接口配合Lambda表达式可以节省性能:

public class Demo01Logger {
    /*
    以下代码存在一些性能浪费的问题
    调用showLog方法,传递的第二个参数是一个拼接后的字符串
    先把字符串拼接好,然后再调用showLog方法
    如果level != 1,拼接操作就会造成性能浪费
     */
    //定义一个根据日志的级别显示日志信息的方法
    public static void showLog(int level, String message){
        //对日志的登集进行判断,如果是1级别,输出日志信息
        if(level == 1)
            System.out.println(message);
    }

    public static void main(String[] args) {
        //定义三个日志信息
        String msg1 = "Hello";
        String msg2 = "World";
        String msg3 = "Java";

        //调用showLog方法
        showLog(1, msg1 + msg2 + msg3);
    }
}

利用Lambda表达式节省性能:
先定义一个函数式接口:

@FunctionalInterface
public interface MessageBuilder {
    String buildMessage();
}

利用Lambda表达式改进:

public class Demo02Lambda {
    //定义一个显示日志的方法,方法的参数传递日志的等级和MessageBuilder接口
    public static void showLog(int level, MessageBuilder mb){
        if(level == 1){
            System.out.println(mb.buildMessage());
        }
    }

    public static void main(String[] args) {
        String msg1 = "Hello";
        String msg2 = "World";
        String msg3 = "Java";

        /*
        使用Lambda表达式作为参数传递,仅仅把参数传递到showLog方法中
        只有满足条件,才会进行字符串的拼接
         */
        showLog(1, () -> {
            System.out.println("level == 1, 字符串拼接");
            return msg1 + msg2 + msg3;
        });
    }
}

常用函数式接口

Supplier

java.util.function.Supplier接口仅包含一个无参的方法:T get()。用来获取一个泛型参数指定类型的对象数据。
Supplier接口被称之为生产型接口,指定接口的泛型是什么类型,那么接口的get方法就产生什么类型的数据。

public class Demo01Supplier {
    public static String getString(Supplier<String> sup){
        return sup.get();
    }

    public static void main(String[] args) {
        String s = getString(() -> "hello!");
    }
}

使用示例:获取数组的最大值

public class Demo02Test {
    public static int getMax(Supplier<Integer> sup){
        return sup.get();
    }

    public static void main(String[] args) {
        int[] arr = new int[]{2,6,1,6,4,8};
        int max = getMax(() -> {
           int temp = arr[0];
            for (int e : arr) {
                if(e > temp)
                    temp = e;
            }
            return temp;
        });
        System.out.println(max);
    }
}

Consumer

和上述Supplier类似,但Consumer接口消费数据。

public class Demo01Consumer {
    public static void consume(String name, Consumer<String> consumer){
        consumer.accept(name);
    }

    public static void main(String[] args) {
        String name = "Bob";
        consume(name, (s) -> System.out.println(new StringBuilder(s).reverse()));
    }
}

AndThen方法的使用:

public class Demo02AndThen {

    public static void consume(String s, Consumer<String> con1, Consumer<String> con2){
        /*con1.accept(s);
        con2.accept(s);*/
        con1.andThen(con2).accept(s);   //先写谁谁先消费数据
    }

    public static void main(String[] args) {
        String s = "Bob";
        consume(s, (o) -> System.out.println(o.toLowerCase()),
                (o) -> System.out.println(o.toUpperCase()));
    }
}

使用示例:
第一个Consumer打印名字,第二个Consumer打印性别。

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

    public static void main(String[] args) {
        String[] arr ={"Bob,male", "John,male", "Lana,female"};
        printInfo(arr, (o) -> {
            String name = o.split(",")[0];
            System.out.print("Name: " + name + " ");
        }, (o) -> {
            String gender = o.split(",")[1];
            System.out.println("Gender: " + gender);
        });
    }
}

Predicate

Predicate类用于进行逻辑判断,它的test方法返回boolean类型。

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

    public static void main(String[] args) {
        String s = "Valar Morghulis";
        boolean isPanlindrome = checkString(s, (o) -> {
            int left = 0, right = o.length() - 1;
            while(left < right)
                if(o.charAt(left) != o.charAt(right)) {
                    return false;
                }
            return true;
        });
        System.out.println(isPanlindrome);
    }
}

Predicate有and、or、nagate三个方法:

public class Demo02Predicate_And {
    //and
    public static boolean checkString1(String s, Predicate<String> pre1, Predicate<String> pre2){
    //return pre1.test(s) && pre2.test(s);
        return pre1.and(pre2).test(s);
    }
    //or
    public static boolean checkString2(String s, Predicate<String> pre1, Predicate<String> pre2){
        return pre1.or(pre2).test(s);
    }
    //negate
    public static boolean checkString3(String s, Predicate<String> pre1, Predicate<String> pre2){
        return pre1.or(pre2).negate().test(s);
    }
    public static void main(String[] args) {
        String s = "Predicate And";
        boolean b1 = checkString1(s, (o) -> o.length() > 5, (o) -> {
            int left = 0, right = o.length() - 1;
            while(left < right)
                if(o.charAt(left) != o.charAt(right)) {
                    return false;
                }
            return true;
        });
        boolean b2 = checkString2(s, (o) -> o.length() > 5, (o) -> {
            int left = 0, right = o.length() - 1;
            while(left < right)
                if(o.charAt(left) != o.charAt(right)) {
                    return false;
                }
            return true;
        });
        System.out.println(b1); //false
        System.out.println(b2); //true
    }
}

使用示例:

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

    public static void main(String[] args) {
        String[] arr ={"Bob,male", "John,male", "Lana,female"};
        ArrayList<String> res = filter(arr, (o) -> {
            String gender = o.split(",")[1];
            return gender.equals("male");
        }, (o) -> {
            String name = o.split(",")[0];
            return name.length() >= 4;
        });
        System.out.println(res.toString());
    }
}

Function

java.util.function.Function<T, R>接口用来根据一个类型的数据得到另一个类型的数据,前者称之为前置条件,后者称为后置条件。
Function接口中最主要的抽象方法为:R apply(T t),根据类型T的参数获取类型R的结果,如String类型转换为Integer类型。

public class Demo01Function {

    public static void change(String s, Function<String, Integer> fun){
        int n = fun.apply(s);
        System.out.println(n);
    }

    public static void main(String[] args) {
        String s = "168530";
        change(s, (o) -> Integer.parseInt(s));
    }
}

Function中的andThen方法:

public class Demo02AndThen {
    public static void change(String s, Function<String, Integer> fun1, Function<Integer, Integer> fun2){
        System.out.println(fun1.andThen(fun2).apply(s));
    }

    public static void main(String[] args) {
        String num = "1265";
        change(num, o -> Integer.parseInt(num), o -> o + 10);
    }
}

使用示例:

public class Demo03Test {

    public static void method(String s, Function<String, String> f1, Function<String, Integer> f2, Function<Integer, Integer> f3){
        System.out.println(f1.andThen(f2.andThen(f3)).apply(s));
    }

    public static void main(String[] args) {
        String s = "Bob,22";
        method(s, o -> o.substring(o.indexOf(",") + 1), o -> Integer.parseInt(o), o -> o + 100);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值