WebFlux前置知识(二)
上篇文章和小伙伴们聊了 Lambda 表达式和函数接口,今天我们一起来看下 方法引用、变量引用、类型推断以及级联表达式四个点,也算是 WebFlux 的一个前置知识点。
废话不多说,开整。 1 方法引用
到今天,方法引用估计很多小伙伴可能多多少少都见过,即使自己没写过,可能也看别人写过。用过的小伙伴可能会感觉这个用着真爽,cool!没用过的小伙伴可能就要吐槽这什么鬼代码。
不管怎么样,我们今天还是来看看方法引用,也算是我们学习 WebFlux 的一个前置知识。 1.1 什么是方法引用
什么是方法引用?
简单说,方法引用就是一个 Lambda 表达式,操作符就是 :: ,有的小伙伴们可能会觉得所谓的 Lambda 就是 -> 代替匿名内部类,其实不然!Lambda 中包含的东西还是蛮多的,方法引用就算是其中之一。
有的时候,我们使用 Lambda,需要自己写方法的实现,但是有的时候,我们可能不需要自己写方法的实现,就是单纯的调用一下方法,这种时候,通过方法名称来调用,会更加清晰,可读性更高,也更加简洁易懂。
方法引用不仅可以用来访问类或者实例中已经存在的方法,也可以用来访问构造方法。 2.2 四种方法引用2.2.1 静态方法引用
例如我定义一个 Lambda,该 Lambda 中有一个方法可以完成对数字格式的转换,如下: public class LambdaDemo05 { public static void main(String[] args) { Function func = a -> String.valueOf(a); String s = func.apply(99); System.out.println("s = " + s); } }
在上面的这个 Function 中,我们将一个 Integer 类型数字转为了一个字符串,由于在 Lambda 中并没有其他代码,就是一个简单的类型转换,因为我们可以将之简写成如下方式: public class LambdaDemo05 { public static void main(String[] args) { Function func = String::valueOf; String s = func.apply(99); System.out.println("s = " + s); } }
类似的,比如我们有一个 Consumer,如下: Consumer consumer = s -> System.out.println(s); consumer.accept("javaboy");
Consumer 消费一个字符串,消费的方式就是控制台打印,这种时候我们可以简写成如下方式: Consumer consumer = System.out::println; consumer.accept("javaboy");
这就是静态方法引用。
再举个例子,用 Lambda 写一个给参数求次幂的函数,如下: BiFunction func = (a, b) -> Math.pow(a, b); Double result = func.apply(3, 4); System.out.println("result = " + result);
传入两个参数类型都是 Integer,返回的数据类型是 Double,调用 Math.pow 计算次幂。
上面这段代码我们也可以通过静态方法引用简化: BiFunction func = Math::pow; Double result = func.apply(3, 4); System.out.println("result = " + result); 2.2.2 实例方法引用
方法引用也可以用在实例方法上。 Random random = new Random(); IntUnaryOperator func = i -> random.nextInt(i); Integer r = func.applyAsInt(10); System.out.println("r = " + r);
这段代码也可以使用方法引用,方式如下: Random random = new Random(); IntUnaryOperator func = random::nextInt; Integer r = func.applyAsInt(10); System.out.println("r = " + r);
就是把类换成实例而已,其他都是一样的。
不过需要注意的是,字符串的实例稍微特殊一些,如下一个字符串排序方法: String[] stringArray = {"Barbara", "Mary", "James"}; Arrays.sort(stringArray,String.CASE_INSENSITIVE_ORDER); System.out.println(Arrays.toString(stringArray));
如果使用方法引用,方式如下: String[] stringArray = {"Barbara", "Mary", "James"}; Arrays.sort(stringArray, String::compareToIgnoreCase); System.out.println(Arrays.toString(stringArray));
这个感觉有点像静态方法引用,其实不是的,Lambda 的第一个参数会成为调用实例方法的对象。
在实例方法引用中,如果需要指定泛型,泛型放在 :: 后面。 2.2.3 构造方法引用
例如如下方法提供一个 Cat 实例: Supplier supplier = () -> new Cat(); Cat cat = supplier.get();
通过方法引用,可以简写成如下形式: Supplier supplier = Cat::new; Cat cat = supplier.get(); 2.2.4 数组构造方法引用
例如创建一个长度为 10 的数组,如下: IntFunction func = (i) -> new int[i]; int[] arr = func.apply(10); System.out.println("arr.length = " + arr.length);
使用构造方法引用,可以简写成如下方式: IntFunction func = int[]::new; int[] arr = func.apply(10); System.out.println("arr.length = " + arr.length); 3. 变量引用
内部类中使用外部定义的变量,需要这个变量是一个 final 类型的,如果用了 Lambda 表达式,这个规则依然适用。
如下; String s = "javaboy"; Consumer consumer = s1 -> System.out.println(s1 + s); consumer.accept("hello ");
此时虽然不用给 s 变量添加 final 标记,但是它实际上已经是 final 类型的了,如果强行修改,就会报错:
4. 类型推断
大部分情况下,Lambda 表达式都是可以推断出自己的类型的,个别情况下可能推断不出,比如出现方法重载的时候,这个时候可能就需要我们类型强转了,例如如下代码: @FunctionalInterface interface ICalculator2{ int add(int a, int b); } @FunctionalInterface interface ICalculator3{ int multiply(int a, int b); } public class LambdaDemo06 { public static void main(String[] args) { calculator((ICalculator2) (a, b) -> a + b); } public static void calculator(ICalculator2 iCalculator) { } public static void calculator(ICalculator3 iCalculator) { } }
上面的代码中定义了两个计算器 ICalculator2 和 ICalculator3,然后有一个重载的方法分别用到了 ICalculator2 和 ICalculator3,这就导致在使用 Lambda 表达式时无法推断出到底使用哪个对象,此时我们就需要显式的进行类型强转。 5. 级联表达式
Lambda 表达式也可以写成 N 多层,具体则看需求。
例如三个数相加,可以写成如下形式: Function>> func = x -> y -> z -> x + y + z; Integer i = func.apply(3).apply(4).apply(5); System.out.println("i = " + i);
这个表达式从右往左看可能容易理解。
z->x+y+z 对应的是 IntFunction 。
z->x+y+z 整体作为返回,y 作为输入,对应的是 Function 。
y -> z -> x + y + z 整体作为返回,x 作为输入,对应的就是 Function> 。
that"s all。
原文链接:https://mp.weixin.qq.com/s/QZYcQFJDxTw0V-E0DTNOIw
被小虫啃食的孩子一初识患者1个月前,门诊来了一对儿患者。分别是一个8个月大的小宝宝,和他的母亲。据宝妈描述,前段时间带孩子回农村老家住了一段时间,可能是由于水土不服所以母子俩先后出现了湿疹,由于症
那些从小在重男轻女家庭长大的女孩,该如何提高自己的核心价值感01那些姑娘的自卑从何而来心理学家胡慎之在在人际关系中成长一书里提过一个案例,有位女士从小在重男轻女家庭长大,父亲脾气暴躁,母亲整天焦虑,哥哥争强好胜。她从小在物质上虽从未受过委屈
英雄联盟中哪些台词让你忍不住喊出来?英雄联盟中每一个英雄都有自己独特的台词,不过相比于整体而言,有些英雄的台词让我们记忆深刻。哪些英雄的台词可以让我们跟他一起喊出来呢?艾欧尼亚昂扬不灭!这句话是在刀妹释放大招剑阵时候
永劫无间S1赛季三排上分阵容推荐吃鸡三排阵容分享永劫无间目前开启了S1赛季的排位玩法,很多玩家都已经开始冲分,而且冲到了很高的位置,很多玩家则不知道用什么阵容比较好吃鸡,三排还是比较吃配置的,下面就来跟随小编一起来看看永劫无间S
热血传奇你爆过最贵的装备是什么?卖了多少钱?03年,46区天煞。当时是个31级小法师,纵横道打了一条邪恶毒蛇,掉了把裁决,当时是准备去练级的,超了一点药还,站上去捡不起来,一个道士已经靠过来了,先给我刷了层绿漆,那个紧张啊,
昨天晚上手机在王者荣耀登陆界面亮屏6小时!对手机危害严重吗?你好,很高兴回答你的问题。首先你用的什么型号手机呢?这个主要是确定它的屏幕是OLED屏幕还是普通的LCD屏幕。如果是OLED屏幕的话,肯定对屏幕损坏比较大的,OLED屏幕亮的时间长
英雄联盟里盲僧RQQ和QRQ打出来的伤害一样吗?大家好,我是史小坑游戏的苦逼小编,每周二五都会为大家带来不一样观点的游戏资讯顺带打个自家游戏硬广,喜欢的朋友别忘了关注我们!!盲僧是很多玩家的信仰,这个英雄在不同玩家手里都能玩出不
dnf旭旭宝宝充了多少钱?据旭旭宝宝亲口所说已经突破了700万人民币,当然是全部花费,从一开始玩就算起的,并不是从直播的算的。对于这个数据,经常看宝哥的小伙伴应该深信不疑吧?就最近俩个月增幅一套15的恍惚1
能不能推荐一些以星际为背景的游戏?这里是喜爱游戏的小白广阔的宇宙,充满着神秘,对于人类来说,在宇宙中探索是一件惬意和享受的事情。碍于现代科技的发展,目前我们还没有办法做到,但是作为游戏来说,广阔的星辰大海已经是我们
坦克世界为什么不火?坦克世界这个游戏只能说在中国火不起来,其他国家相对于我们来说要热情的多。玩了五六年我认为不火的原因有以下几点1这个游戏对新手很不友好!坦克世界是一个很值得玩和推敲的游戏,因为坦克的
如何看待玩英雄联盟却不知道opgg的人?说真的本人从s2开始接触lol到现在也一直没有断过,你说的那个什么opgg真的是没听过我玩个游戏图个乐子,知道那么多干嘛呀,开心就好啦。非得要看国外数据才能找到优越感嘛?不知道op