正文
jdk8新特性之双冒号 :: 用法及详解
原
荐
字数 645
阅读 32
收藏 3
JDK
jdk8的新特性有很多,最亮眼的当属函数式编程的语法糖,本文主要讲解下双冒号::的用法。
类名::方法名,相当于对这个方法闭包的引用,类似js中的一个function。比如:
Function<String,String> func = String::toUpperCase;
(Function在java.util.function包下,也是jdk8新加入的类,同级目录下有很多函数式编程模型接口,比如Consumer/Predicate/Operator等)
func相当于一个入参和出参都为String的函数,可以直接
func.apply("abc")
接收一个参数,返回一个结果("ABC")。也可以用于代替下面的Lambda表达式:
List<String> l = Arrays.asList("a","b","c"); l.stream().map(s -> s.toUpperCase()); l.stream().map(func);
下面自定义一个函数式接口
public class MyConsumer<String> implements Consumer<String> { @Override public void accept(String s) { System.out.println(s); } }
下面这俩种写法等价:
List<String> l = Arrays.asList("a","b","c"); l.forEach(new MyConsumer<>()); l.forEach(s -> System.out.println(s));
但是,这种写法却不行,编译失败:
l.forEach(MyConsumer::accept);
因为MyConsumer的accept方法不是静态的,如果想使用这个方法,需要一个实例,还需要一个入参,共俩个参数。而List.forEach中需要的是consumer类型,相当于 s -> {...}
,只有一个参数。
新建一个类,里面声明四个代表各种情况的方法:
public class DoubleColon { public static void printStr(String str) { System.out.println("printStr : " + str); } public void toUpper(){ System.out.println("toUpper : " + this.toString()); } public void toLower(String str){ System.out.println("toLower : " + str); } public int toInt(String str){ System.out.println("toInt : " + str); return 1; } }
把它们用::提取为函数,再使用:
Consumer<String> printStrConsumer = DoubleColon::printStr; printStrConsumer.accept("printStrConsumer"); Consumer<DoubleColon> toUpperConsumer = DoubleColon::toUpper; toUpperConsumer.accept(new DoubleColon()); BiConsumer<DoubleColon,String> toLowerConsumer = DoubleColon::toLower; toLowerConsumer.accept(new DoubleColon(),"toLowerConsumer"); BiFunction<DoubleColon,String,Integer> toIntFunction = DoubleColon::toInt; int i = toIntFunction.apply(new DoubleColon(),"toInt");
非静态方法的第一个参数为被调用的对象,后面是入参。静态方法因为jvm已有对象,直接接收入参。
再写一个方法使用提取出来的函数:
public class TestBiConsumer { public void test(BiConsumer<DoubleColon,String> consumer){ System.out.println("do something ..."); } }
下面这俩种传入的函数是一样的:
TestBiConsumer obj = new TestBiConsumer(); obj.test((x,y) -> System.out.println("do something ...")); obj.test(DoubleColon::toLower);
用::提取的函数,最主要的区别在于静态与非静态方法,静态方法比非静态方法多一个参数,就是被调用的实例。
© 著作权归作者所有
共有人打赏支持
粉丝 3
博文 6
码字总数 7170
作品 0
沈阳
程序员
相关文章 最新文章
今天上午同事问我 rsync -av /SRC root@172.17.256.211:36000::/DEST 为何报 port 22 refused 的错误? 因为我们机器都是修改了 ssh 端口的,默认22端口是登录不上ssh的, 同事的本意是想修改...
大数据之路
2012/08/27
0
0
CSS 的伪类选择器和伪元素选择器,让 CSS 有了更为强大的功能。 伪类大家听的多了,伪元素可能听到的不是那么频繁,其实 CSS 对这两个是有区分的。 有个错误有必要每次讲到伪类都提一下,有时...
chokcoco
08/02
0
0
CSS 有两个说不上常用的伪类 :before 和 :after,偶尔会被人用来添加些自定义格式什么的,但是它们的功用不仅于此。前几天发现了 Creative Link Effects 这个非常有意思的介绍创意链接特效的...
issac宝华
2016/11/01
40
0
为什么要单独写个Java8新特性,一个原因是我目前所在的公司用的是jdk8,并且框架中用了大量的Java8的新特性,如上篇文章写到的stream方法进行过滤map集合。stream方法就是接口Collection中的...
阳光温暖
07/31
0
0
学习JDK8新特性,必不可少的就是函数式编程,那也就不得不了解Function接口的使用了。 首先看下Function接口的定义 接口定义了两个泛型,在使用的时候需要指定。 该接口中比较重要的就是这个...
十月阳光
2017/10/18
0
0
没有更多内容
加载失败,请刷新页面
加载更多接着第一部分说,爬虫就是请求网站并提取数据的自动化程序。其中请求,提取,自动化是爬虫的关键!接下来看看流程。 1.爬虫的基本流程 发起请求 通过HTTP库向目标站点发起请求,也就是发送一个...
China丶小可
22分钟前
1
0
vue与react,到目前为止两个我都用来写了好多项目,vue用的脚手架是vue-cli,react用的是dva,两者都对其进行了很好的封装,只需要简单的几步就能跑起来. 之前在国外一大神讨论这两者之间的区域,...
前端大白
28分钟前
1
0
log4j使用DailyRollingFileAppender DailyRollingFileAppender是日志记录软件包Log4J中的一个Appender,它能够按一定的频度滚动日志记录文件。 我们可以按下面的方式配置DailyRollingFileApp...
hotsmile
30分钟前
1
0
Scrapy 是一个用 Python 开发的爬虫框架,用于抓取 Web 页面并提取其中的结构化数据。 安装 首先,确定你的电脑上已经安装了 Python 3 以及对应的 pip。可以使用下面的命令查看: $ python3 ...
linuxprobe16
51分钟前
0
0
写个项目,要求要本地上传音视频至服务器,再回显可播放。 当前项目使用了elementUI+Vue 上传图片,请求接口,将图片或者音频文件提交给后台,后台返回存储图片或者音频的ID,因为后台存到m...
李晓艳
54分钟前
1
0
没有更多内容
加载失败,请刷新页面
加载更多