Java行为参数化(一)

一.什么是行为参数化呢 说白了就是将一段行为当作参数传入一个方法中呗,那么这段行为是什么呢?

答:那也是一个方法咯。

Java在1.8版本引入了行为参数化的概念,首先,我们先看一小段代码

public class test { public static void main(String[] args){ Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };

    show(consumer ,"hello world");
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
复制代码

} 输出结果当然是:hello world 啦。

可是你想这有什么呢?不就是写了一个Consumer接口,然后写一个匿名类重写他的accept方法,然后带入Consumer到show方法调用它咩?Java没更新前也可以这样啊,只不过是传参了一个对象,然后在方法内调用了对象的方法。

那么我们再来看看下面这段代码,看看它和上面的代码有什么不同:

public class test { public static void main(String[] args){ /Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };/

    show(System.out::println ,"hello world");
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
复制代码

} 注意!代码中3到8行已经注释了哦。

现在看看:show方法接受一个Consumer对象和字符串,然后调用对象的accept方法,这里都没变;可是著方法中调用show方法的时候传递的第一个参数不再是Consumer对象了,而是System.out::println,而这是什么意思呢?

System.out::println 是方法引用,方法引用的格式就是:类名::方法名 或者 对象名::成员方法名

我们都知道,在方法重写和重载中我们是怎么做的呢?在子类中写一个和主类中被重写方法方法名相同、参数类型、顺序相同的方法,那jdk是根据什么来判断是否是重写或者重载呢?没错,就是靠函数签名来判断的,就比如上面代码中的show方法,它的函数签名就是:名为show、接受两个参数并且第一个参数是Consumer类型、第二个参数是String类型的函数,如果返回类型相同,则是重写;否则是重载。Java根据你的方法引用来确定你的方法签名和返回类型,如果和形参中Consumer对象中的方法相同的话,就可以使用。

那么我们回到代码中去,我们在主方法中调用show方法时传入的第一个参数就是一个:无返回值,接受一个泛型参数的方法签名的方法引用。

你也可以传入其他方法进去,只要方法签一致就可以啦。就像下面一样:

public class test { public static void main(String[] args){ /Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };/ test one = new test();

    show(one::otherMethod ,"hello world");
}public void otherMethod(T t){int i = 0;System.out.println(i + t.toString());
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
复制代码

} 结果是输出:0hello world

你也可以将show方法的第二个参数换成一个集合,然后在第一个参数中传入其他方法引用来对集合进行操作哦。

在上面我们说到在带哦用show方法时传入的方法引用的方法签名、返回类型要和Consumer对象中方法的一致,那么这个Consumer到底是什么呢?它的内部只有一个方法吗?如果有多个方法的话怎样根据传入的方法引用和他的众多方法比较呢?

答:Consumer其实是一个接口,一个函数式接口,话不多说,直接上源码

package java.util.function;

import java.util.Objects;

@FunctionalInterface public interface Consumer {

void accept(T t);default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };
}
复制代码

} 大家看,是不是感觉有些不对呢?Java接口明明不能所有实现方法的,现在却多了一个default方法被实现,嘿嘿,这是Java8的新特性,这个我会在之后的帖子中继续和大家分享。大家要注意的是@FunctionalInterface这个注解,它表明这个接口是一个函数式接口,函数式接口的定义就是:一个有且只有一个抽象方法,但是可以有多个非抽象方法的接口。非抽象方法就是default方法,可以有多个,但是抽象方法只能有一个,那么上面关于传入方法引用怎样匹配方法签名和返回值的疑问你们理解了吗?

就是说在上面的例子中我在show方法定义的Consumer中只有一个抽象方法accept,他是一个无返回值,接受一个泛型参数的方法,而我在调用show方法的时候也传入了和accept方法返回值一致,参数相同的方法引用,这就是方法重写,在上面的例子中我传入System.out::println时就是无形之中创建了一个匿名类,然后重写了他的accept方法,重写的方法就是System.out.println()方法。神奇咩?嘿嘿...

等等,还没完...Consumer接口提供一个无返回值类型接受一个参数的抽象方法供大家使用,那么如果我有其他需求呢?假如我需要一个有返回值的抽象方法供我使用呢?

别急,Java提供了一系列函数式接口来供我们按照需求使用,如果没有自己需要的接口的话我们也可以自己写一个函数式接口来使用。

函数式接口 函数描述符 Predicate T->boolean Consumer T->void Function<T,R> T->R Supplier ()->T UnaryOperator T->T BinaryOperator (T,T)->T

BiPredicate<L,R> (L,R)->boolean BiConsumer<T,U> (T,U)->void BiFunction<T,U,R> (T,U)->R 函数描述符是什么呢?这就要说到Lambda表达式了,在下一篇博客中我会讲解。(本人是小白大学生一枚,如有不对或者不当之处,还请各位前辈指点,嘿嘿)

转载于:https://juejin.im/post/5c39af8a518825265c2fd86a

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

猴子排圈求最后编号问题

转载链接&#xff1a;http://www.cnblogs.com/mztest/archive/2013/01/30/2882829.html 一群猴子排成一圈&#xff0c;按1&#xff0c;2&#xff0c;...&#xff0c;n依次编号。然后从第1只开始数&#xff0c;数到第m只,把它踢出圈&#xff0c;从它后面再开始数&#xff0c;再…

若川的2020年度总结,水波不兴

前言从2014年开始&#xff0c;每一年都会写年度总结&#xff0c;坚持了6个年头。回顾2014&#xff0c;约定2015&#xff08;QQ空间日志&#xff09;2015年总结&#xff0c;淡化旧标签&#xff0c;无惧未来&#xff08;QQ空间日志&#xff09;2016年度总结&#xff0c;毕业工作2…

sql修改表字段数据类型

--加 ALTER TABLE table2 ADD row_id bigint --删 ALTER TABLE table2 DROP COLUMN row_id --改 ALTER TABLE 你的表 ALTER COLUMN 列名 你的类型 null declare a varchar(200) select ac.name fr…

关于敏捷开发方法(Agile Software Development)的阅读笔记

对“敏捷开发”&#xff08;Agile Software Development&#xff09;这个词&#xff0c;我是在这学期邹欣老师《现代程序设计》课上第一次听到的&#xff0c;刚听到时并不知道其具体指什么&#xff0c;只是从字面上直觉其意思应该是快速开发之类的。这次从 Agile Guide 、 The …

phpbreak跳出几层循环_PHP跳出循环之“break”

前面给大家讲解了PHP控制循环语句&#xff0c;知道了&#xff0c;当我们的程序块满足一定的条件后才会跳出循环&#xff0c;而跳出循环则是使用我们的break或者continue关键字。本章&#xff0c;将会先给大家讲解“break”跳出循环。在前面的讲解PHP循环控制语句“while”循环的…

Vuex 4.0 正式发布!新年,官方生态齐聚一堂。

Vuex 4 官方版本正式发布。Vuex 4 的重点是兼容性。Vuex 4 支持 Vue 3&#xff0c;但是仍然提供了与 Vuex 3 完全相同的 API&#xff0c;因此用户可以在 Vue 3 中直接复用他们现有的 Vuex 代码。下文会把破坏性的改动列出来&#xff0c;请注意查看。在源码的 example 文件夹[1]…

原生js实现给指定元素的后面追加内容

参考链接&#xff1a;http://www.jb51.net/article/35412.htm 原生js实现给指定元素的后面追加内容 var header1 document.getElementById("header"); var p document.createElement("p"); // 创建一个元素节点 insertAfter(p,header1); // 因为js没有…

文档中根元素后面的标记格式必须正确。

文档中根元素后面的标记格式必须正确。 php或其它语言动态输出的xml&#xff0c;最开始<标记 前面有空格&#xff0c;最后面>标记 后面有 空格 导致xml解析出错 解决办法: var data:String evt.target.data;//兼容FireFox, php输出的xml data data.substr(data…

lstm数学推导_如何在训练LSTM的同时训练词向量?

你本来也不用自己手动进行词向量更新啊&#xff0c;你搞这么一出最后收敛到0那不是必然的么&#xff1f; 霍华德 老师的答案已经给你推导出来了。实际上你问的这个问题很简单——只要把Embedding层本身也当成模型参数的一部分就可以了&#xff0c;一开始不使用外部词向量&#…

Javascript在页面加载时的执行顺序(转载)

原文&#xff1a;http://dancewithnet.com/2007/03/22/order-of-execution-of-javascript-on-web/ 一、在HTML中嵌入Javasript的方法 直接在Javascript代码放在标记对<script>和</script>之间由<script />标记的src属性制定外部的js文件放在事件处理程序中&a…

TClientDataSet[27]: 字段值的约束(或叫输入限制)

Required、Precision、MaxValue、MinValue:begin{ Required: 必填字段 }with TIntegerField.Create(Self) do beginFieldName : ID;Required : True;DataSet : ClientDataSet1;end;{ Precision: 浮点数精度}with TFloatField.Create(Self) do beginFieldName : Float;Precision…

年度总结文章的抽奖结果公布

大家好&#xff0c;我是若川。2月4日&#xff0c;发表了我的2020年度总结文章《若川的2020年度总结&#xff0c;水波不兴》&#xff0c;本以为阅读量应该突破一千会比较快&#xff0c;实际上比较艰难&#xff0c;而且还掉粉10来人。2020年运营公众号以来&#xff0c;不知不觉发…

php 正则表达式 匹配中日韩字符(GBK)

转载链接&#xff1a;http://www.cnblogs.com/ITEagle/archive/2013/01/14/2859775.html 首先是这些非英文字符的编码范围&#xff1a; 这里是几个主要非英文语系字符范围 2E80&#xff5e;33FFh&#xff1a;中日韩符号区。收容康熙字典部首、中日韩辅助部首、注音符号、日本假…

linux多线程求和_linux 多线程信号处理总结

linux 多线程信号总结(一)1. 在多线程环境下&#xff0c;产生的信号是传递给整个进程的&#xff0c;一般而言&#xff0c;所有线程都有机会收到这个信号&#xff0c;进程在收到信号的的线程上下文执行信号处理函数&#xff0c;具体是哪个线程执行的难以获知。也就是说&#xff…

Elon Musk

人物事件 成长学习 1971年6月28日&#xff0c;埃隆马斯克在南非的比勒陀利亚出生&#xff0c;他的 埃隆马斯克 父亲是一名南非机电工程师&#xff0c;母亲是加拿大人&#xff0c;从事营养师兼模特。[8] 1981年&#xff0c;10岁的马斯克就拥有了自己的第一台电脑&#xff0c;并…

真诚推荐这7个大佬的公众号,碎片化学习

逆水行舟&#xff0c;不进则退。我们的工作已经占用了大块的时间了&#xff0c;剩下的只有各种碎片&#xff0c;最适合碎片时间学习的&#xff0c;莫过于优质的技术干货公众号啦~以下这些是小编精选&#xff0c;里面有很多资讯和资源&#xff0c;内含干货&#xff0c;希望能给大…

[转]Windows 7 产品密钥是否安全

提到Windows 7&#xff08;或Windows Server 2008&#xff09;有些人认为自己的产品密钥&#xff08;Product Key&#xff09;很安全&#xff0c;甚至在公司内部有些网管也认为公司部署的Windows 7 系统的密钥不会泄露。但其实并非如此&#xff0c;众所周知我们的密钥都是写在注…

HttpWatch的Result中出现Aborted的原因分析[配图]

转载链接&#xff1a;http://www.cnblogs.com/yutiansanshou/archive/2013/02/01/2889486.html 我们在使用HttpWatch进行Web调试的过程中有时候会看到非HTTP Status Code&#xff08;状态码&#xff09;的值&#xff0c; 例如&#xff1a;(Aborted)。 (Aborted)是HttpWatch中定…

android显示布局边界的边距_Android设计规范 Material Design-Layout(2 度量与边框)

度量与边框基准网络所有组件都与间隔为8dp的基准网格对齐。排版/文字(Type)与间隔为4dp的基准网格对齐。在工具条中的图标同样与间隔为4dp的基准网格对齐。这些规则适用于移动设备、平板设备以及桌面应用程序。有关详细信息请参见组件一节。有关详细信息请参见字体排版一节。边…

《大规模分布式系统架构与设计实战》

《大规模分布式系统架构与设计实战》 基本信息 作者&#xff1a; 彭渊 丛书名&#xff1a; 大数据技术丛书 出版社&#xff1a;机械工业出版社 ISBN&#xff1a;9787111455035 上架时间&#xff1a;2014-2-21 出版日期&#xff1a;2014 年2月 开本&#xff1a;16开 页码&…