当前位置: 首页 > news >正文

Java Lambda表达式:简洁高效的函数式编程

1  lambda表达式

  • Lambda 表达式本质是一个匿名函数,用于把函数作为参数,传入方法中,实现函数式编程风格。

  • 使用Lambda 表达式可以使代码变的更加简洁紧凑。

语法格式

(parameters)-> expression (parameters)->{ statements;}

示例:

public class Demo01 {public static void main(String[] args) {Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("子线程1开始执行任务");}});t1.start();//lambda表达式写法Thread t2 = new Thread(()-> System.out.println("子线程2开始执行任务"));t2.start();}
}

使用匿名内部类
1.定义了一个没有名字的类
2.这个类实现了Runnable接口
3.重写了run方法,实例化这个匿名内部类对象
冗余
其实最关注的是run方法里面要执行的代码
lambda表达式体现的是函数式编程思想,只需要将需要执行的代码放到函数中
lambda表达式是一个匿名函数

public class Demo02 {public static void main(String[] args) {swim(new ISwim(){@Overridepublic void swimming() {System.out.println("Forg游泳");}});System.out.println("----------------------------");//lambda相当于对接口抽象方法的重写swim(()->System.out.println("Hello World"));}public static void swim(ISwim s) {System.out.println("进入swim方法中");s.swimming();System.out.println("结束swim方法");}
}//无参,无返回值
interface ISwim{void swimming();
}

 lambda可以创建函数式接口
函数式接口:@FunctionalInterface
接口中的有且仅有一个抽象方法的接口,称为函数式接口(静态方法,默认方法,抽象方法只有一个)
语法格式:
接口名  对象名 = (参数类型1  参数名1,...参数类型n  参数名n) ->{方法体;}
参数类型n 参数名n:接口中抽象方法的参数项
->:表示连接操作
{}:存放重写的方法体内容,可以理解为对抽象方法的覆盖。

 简写:
1.参数类型可以简写
2.小括号,当参数只有1个时,可以省略
3.{}、return:同时进行省略,方法体语句只有一条时

public class Demo03 {public static void main(String[] args) {List<Integer> list = Arrays.asList(2,6,4,7,5,1,9,0,8,3);
//        list.sort(new Comparator<Integer>() {
//            @Override
//            public int compare(Integer o1, Integer o2) {
//                return o1 - o2;
//            }
//        });//lambda表达式
//        list.sort((Integer i1, Integer i2) ->{return i2-i1;});//删除了全部的参数类型
//        list.sort((o1, o2) -> {return o1 - o2;});//删除了{} return ;list.sort((o1, o2) -> o1 - o2);System.out.println(list);}
}

2  函数式接口Functional Interface

只有一个抽象方法的接口(可以定义多个非抽象方法)。可以使用@FunctionalInterface接口定义,强化语义规范。

函数式接口,也被称为SAM 接口(Single Abstract Method Interfaces

作用

基于函数式接口,可以使用Lambda表达式进行实现,实现函数式编程。

目标:

  • 了解内置函数式接口由来
  • 了解常用内置函数式接口

常用内置函数式接口介绍

Java 8 中专门有一个包放函数式接口java.util.function,该包下的所有接口都有 @FunctionalInterface 注解,提供函数式编程方式。下面是最常用的几个接口。

1  Supplier接口 -- 供给型接口

java.util.function.Supplier<T> 接口 - 方法没有参数,有返回值--供给型接口。

它意味着"供给" , 对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。

供给型接口,通过Supplier接口中的get方法可以得到一个值,无参有返回的接口。

public class Demo01 {public static void main(String[] args) {System.out.println("进入到了man方法");printMax(()->{System.out.println("进入到get方法中了");Integer[] arrays={1,2,3,4,5};Integer num=Collections.max(Arrays.asList(arrays));System.out.println("在get中找到最大值:"+num);return num;});int n=number(()->{Random random=new Random();int num;while(((num=random.nextInt(11,20)) & 1)!=0){}return num;});System.out.println("随机整数为:"+n);}public static void printMax(Supplier<Integer> supplier){System.out.println("进入到printMax方法中了");Integer max = supplier.get();System.out.println("printMax返回值为:"+max);}public static Integer number(Supplier<Integer> supplier){return supplier.get();}
}

2  Consumer接口 --消费型接口

java.util.function.Consumer<T> 接口则正好相反 --方法有参数,没有返回值,它不是生产一个数据,而是消费一个数据,其数据类型由泛型参数决定。 --消费型接口

Consumer消费型接口,可以拿到accept方法参数传递过来的数据进行处理, 有参无返回的接口。

public class Demo02 {public static void main(String[] args) {//转小写caseLetter(t-> System.out.println(t.toLowerCase()),"HelloWorld");//转大写caseLetter(t-> System.out.println(t.toUpperCase()),"HelloWorld");//先转小写,再转大写caseLetters(t-> System.out.println(t.toLowerCase()),t-> System.out.println(t.toUpperCase()),"HelloWorld");}public static void caseLetter(Consumer<String> consumer,String str){consumer.accept(str);}public static void caseLetters(Consumer<String> consumer1,Consumer<String> consumer2,String str){consumer1.andThen(consumer2).accept(str);}}

3  Function接口 --转换型接口

java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件, 后者称为后置条件。有参数有返回值。----- 此方法接收一个参数,加工处理成另一种,称为转换型接口

Function转换型接口,对apply方法传入的T类型数据进行处理,返回R类型的结果,有参有返回的接口。使用的场景 例如:将 String类型转换为 Integer类型。

public class Demo03 {public static void main(String[] args) {//1.获取字符串的长度Function<String, Integer> f = s -> s.length();test(f,"1234abc");//2.截取字符串的前三位,将其转换为数字test(string -> Integer.parseInt(string.substring(0,3)),"1234abc");//3.test(string -> string.length(),len->new int[len],"abcde");}public static void test(Function<String,Integer> function,String str) {Integer num = function.apply(str);System.out.println(num);}/*function1  获取字符串长度的方法function2  获取指定长度的int类型的数组*/public static void test(Function<String,Integer> function1,Function<Integer,int[]> function2,String str) {
//        Integer num = function1.apply(str);
//        int[] ints = function2.apply(num);
//        System.out.println(num);
//        System.out.println(Arrays.toString(ints));int[] arr=function1.andThen(function2).apply(str);System.out.println(Arrays.toString(arr));}
}

4  Predicate接口--断言型接口

有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用

java.util.function.Predicate<T> 接口。------接收一个参数,返回一个boolean类型的值,称为判断型接口

public class Demo04 {public static void main(String[] args) {int number=new Random().nextInt(200);//1.判断此数字是否大于等于100method(num->num>=100,number);//2.判断此数字是否为偶数method(num->(num&1)==0,number);method(num->num>=0,num->(num&1)==0,number);}public static void method(Predicate<Integer> predicate,Integer num) {boolean result = predicate.test(num);System.out.println("数字num:"+num+" 判断后的结果为:"+result);}public static void method(Predicate<Integer> predicate1,Predicate<Integer> predicate2,Integer num) {boolean result1 = predicate1.and(predicate2).test(num);System.out.println("数字num:"+num+" 是否大于100并且为偶数?"+result1);boolean result2 = predicate1.or(predicate2).test(num);System.out.println("数字num:"+num+" 是否大于100或者为偶数?"+result2);boolean result3 = predicate1.negate().test(num);System.out.println("数字num:"+num+" 是否不大于100?"+result3);boolean result4 = predicate2.negate().test(num);System.out.println("数字num:"+num+" 是否不为偶数?"+result4);}
}

5  Comparator接口--比较器接口

比较器接口,用于比较指定元素值的大小。Java8版本中,添加了多个新的default方法,用于比较器合并、反转等操作。

// 案例数据
List<String> langList = Arrays.asList("Basic", "QBasic","HTML", "c", "c++", "PowerBuilder", "go", "Visual Basic", "c#","java");// 按照ASCII码比较
Comparator<String> comparator1 = (s1, s2) -> {return s1.compareTo(s2);
};// 按照长度比较
Comparator<String> comparator2 = (s1, s2) -> {return s1.length() - s2.length();
};// 先比较长度,再比较ASCII码
Comparator<String> comparator3 = comparator2.thenComparing(comparator1);// 在comparator3的基础上,反转条件
Comparator<String> comparator4 = comparator2.reversed();// 按照指定Comparator,进行排序
langList.sort(comparator2);
http://www.dtcms.com/a/320205.html

相关文章:

  • 关于光猫研究
  • 【代码随想录day 14】 力扣 101. 对称二叉树
  • 技法笔记3 | 验证交互式shell连接
  • LocalSqueeze(图片压缩工具) v1.0.4 压缩
  • 美图复现|Science:添加显著性的GO富集分析美图
  • Nuxt 4.0 完全指南:Nitro 引擎升级与 Composable API 深度解析
  • 关于Android studio调试功能使用
  • 如何选择适合中小企业的OA系统?XKOA低成本高定制化方案详解
  • 数据可视化Matplotlib
  • 【AI智能编程】Cursor IDE工具学习
  • P1037 [NOIP 2002 普及组] 产生数
  • vue-plugin-hiprint 打印模版使用
  • 【IQA技术专题】大模型评级IQA:Q-Align
  • 深入理解“进程屏蔽字“(Signal Mask)
  • 利用OpenVINO™ Day0快速部署端侧可用的MiniCPM-V4.0视觉大模型
  • 【代码随想录day 14】 力扣 226.反转二叉树
  • C语言memcpy函数详解:高效内存复制的实用工具
  • uniapp-vue2导航栏全局自动下拉变色
  • 损耗对信号质量的影响
  • OpenAI 开源 GPT-OSS:大型语言模型的开放时代正式来临!
  • HTTP请求头详解:从基础到实战
  • 当函数返回有多个返回值时,需要注意的问题 : Effective Python 第19条
  • C++ vector 扩容时到底发生了什么?
  • 一个程序通过 HTTP 协议调用天气 API,解析 JSON 格式的天气数据,提取关键信息并格式化输出:日期、天气状况、温度范围、风向、湿度等核心气象数据。
  • 1688 商品详情接口开发实战:从平台特性到高可用实现
  • Redis最新安装教程(WindowsLinux)
  • 对基带信号进行调制的原因及通俗理解
  • HR人才测评工具,卡特尔16pf性格测试
  • Numpy科学计算与数据分析:Numpy数学函数入门与实践
  • 我爱发明之Linux下使用Conky在桌面显示Spotify状态及封面字符画