函数式接口及lambda表达式优化函数式接口

最近入职了滴滴,在看公司业务代码的时候发现代码中使用到了大量的stream流方式来简化代码,这对于没有接触过stream流的人来说看起来是十分费劲的,所以我打算写一个专题来讲解一下stream流的一些操作和代码书写!

目录

一,函数式接口

1.1 前言

1.2 函数式接口

 二,函数式接口的使用

2.1 函数式接口作为参数

2.2 函数式接口作为返回值(返回值是一个函数式接口)

三,函数式接口结合Lambda表达式的练习

3.1  练习一

3.2  练习二

3.3 练习三


 有关Stream流及函数式编程的相关代码均在我的码云上查看:徐明园/JavaCode - Gitee.com

并内附了详细的Stream流README文档:

一,函数式接口

1.1 前言

在了解Stream流之前我们需要先了解一下Lambda表达式,而Lambda表达式就是Java中函数式编程的体现,所以我们先来讲解一下什么是函数式接口(函数式接口就是可以适用于Lambda使用的接口)。

1.2 函数式接口

什么样的接口可以称作为函数式接口,一般认为接口中有且仅有一个抽象方法(默认方法和static方法除外)的接口称为函数式接口,具体格式如下:

修饰符 interface 接口名称{
   public abstract 返回值类型 方法名称(可选参数信息);  //public abstract可省略
   //其他非抽象方法内容(其他方法不影响)
}

或者使用了@FunctionalInterface注解(该注解的作用就是检测一个接口是不是函数式接口),你可以简单的理解为这个注解起到了一个Mark的作用,只是为了告诉编译器此接口是否是函数式接口(功能类似于Serializable只是标记该类是否可以序列化),我们在查看源码的时候可以看到我们一些常用的接口,如Runnable,Comsumer等接口的源码上都加上了@FunctionalInterface注解:

 同时我们自己可以定义函数式接口,主要需要注意的是接口中有且仅有一个抽象方法,为了保险起见,我们也可以加上@FunctionalInterface注解,如果接口内的方法满足函数式接口的规范则该注解会编译通过,否则会编译失败:

仅有一个抽象方法时加上@FunctionalInterface注解编译通过:

/**
 * 有且仅有一个抽象方法method时加上注解编译通过
 */
@FunctionalInterface
interface MyInterface {
    void method();
}

超过一个抽象方法时加上@FunctionalInterface注解编译失败: 

/**
 * 有两个抽象方法method method1时加上注解编译失败
 */
@FunctionalInterface
interface MyInterface {
    void method();
    void method1();
}

 二,函数式接口的使用

函数式接口的使用按照大类可以分为两大类(细分参数个数的话种类更多,不做深究,希望读者可以举一反三):

2.1 函数式接口作为参数
public class FunctionalUseDemo1 {
    //定义一个方法threadStart,参数使用函数式接口Runnable
    public static void threadStart(Runnable runnable){
        new Thread(runnable).start();
    }
​
    public static void main(String[] args) {
        //调用threadStart方法,方法的参数是一个接口,可以传递这个接口的匿名内部类
        threadStart(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"开启线程");
            }
        });

        //使用Lambda表达式优化
        threadStart(()->System.out.println(Thread.currentThread().getName()+"开启线程"));
    }
}
2.2 函数式接口作为返回值(返回值是一个函数式接口)
public class FuntionalUseDemo2{
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(9);
        list.add(2);
        list.add(5);
        list.add(1);
        System.out.println("排序前: " + list);
        Collections.sort(list,getComparator());
        System.out.println("---------------------");
        System.out.println("排序后: " + list);

    }

    public static Comparator<Integer> getComparator() {
        return new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        };

        //lambda表达式优化
        return (o1, o2) -> o1 - o2;
    }
}

注意:所有函数式接口均可以使用Lambda表达式进行优化,优化的核心是只关注参数和方法体内的具体执行,方法名及其他不需要关注! 

三,函数式接口结合Lambda表达式的练习

下面给出三个练习题,读者先将函数式接口转换成匿名内部类表达式,再通过匿名内部类表达式优化成Lambda表达式(记住转换成Lambda表达式时候只关注参数和方法体内具体执行):

3.1  练习一
import java.util.function.IntBinaryOperator;

public class LambdaDemo1 {
    public static void main1(String[] args) {
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("线程执行!");
//            }
//        }).start();

        new Thread(() -> {
            System.out.println("线程执行");
        }).start();
    }

    public static void main(String[] args) {
        IntBinaryOperator operator = new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        };
        int ret = calc(operator);
        System.out.println(ret);
    }

    public static int calc(IntBinaryOperator operator) {
        int a = 10;
        int b = 20;
        return operator.applyAsInt(a, b);
    }

}
3.2  练习二
import java.util.function.IntBinaryOperator;

public class LambdaDemo2 {

    public static void main1(String[] args) {
        IntBinaryOperator operator = new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        };
        int ret = calc(operator);
        System.out.println(ret);
    }

    public static void main2(String[] args) {
        int ret = calc(new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        });
        System.out.println(ret);
    }

    public static void main(String[] args) {
        int ret = calc((int left, int right) -> {
            return left + right;
        });
        System.out.println(ret);

    }

    public static int calc(IntBinaryOperator operator) {
        int a = 10;
        int b = 20;
        return operator.applyAsInt(a, b);
    }
}
3.3 练习三
import java.util.function.IntPredicate;

public class LambdaDemo3 {


    public static void main(String[] args) {
        printNum(new IntPredicate() {
            @Override
            public boolean test(int value) {
                return value % 2 == 1;
            }
        });
}

//    public static void main1(String[] args) {
//        printNum((int value) -> {
//            return value % 2 == 1;
//        });
//
//    }

    public static void printNum(IntPredicate predicate) {
        int[] arr = {1, 2, 3, 4, 5};
        for (int i : arr) {
            if(predicate.test(i)) {
                System.out.println(i);
            }
        }
    }
}

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
函数式接口是指只有一个抽象方法的接口。它们可以被用作lambda表达式的目标类型,使得我们能够以更简洁的方式定义和使用匿名函数。 Lambda表达式是一种匿名函数,它可以作为参数传递给方法或存储在变量中。它提供了一种更简洁、更灵活的方式来编写代码。在Java 8之前,我们使用匿名内部类来实现类似的功能。但是,使用Lambda表达式可以更直观地表达代码的意图,使代码更易读和易于维护。 Lambda表达式可以在很多场景中使用,其中包括事件处理和迭代列表。在事件处理方面,Lambda表达式可以用来替代传统的匿名内部类,使代码更简洁。例如,使用Lambda表达式可以更好地处理Swing API中的事件监听代码。 在迭代列表方面,Lambda表达式可以用来替代传统的for循环,使代码更简洁和可读性更高。例如,使用Lambda表达式可以更方便地对列表进行迭代,可以使用forEach方法来实现。 总的来说,函数式接口Lambda表达式Java 8中引入的功能,它们可以使代码更简洁、更灵活,并提供了更好的方法来处理事件和迭代列表。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java Lambda表达式函数式接口实例分析](https://download.csdn.net/download/weixin_38688145/12746209)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Lambda表达式函数式接口详解](https://blog.csdn.net/weixin_43552143/article/details/122364188)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值