转载

原 荐 jdk8新特性之双冒号 :: 用法及详解

wangbo888的个人空间 jdk

正文

原 荐 jdk8新特性之双冒号 :: 用法及详解

jdk8新特性之双冒号 :: 用法及详解

原 荐 jdk8新特性之双冒号 :: 用法及详解
  wangbo888 发布于 今天 16:43

字数 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);

总结

用::提取的函数,最主要的区别在于静态与非静态方法,静态方法比非静态方法多一个参数,就是被调用的实例。

© 著作权归作者所有

共有人打赏支持

原 荐 jdk8新特性之双冒号 :: 用法及详解

wangbo888

粉丝 3

博文 6

码字总数 7170

作品 0

沈阳

程序员

相关文章 最新文章

关于 rsync 中: 和 :: 及 rysnc 和 ssh 认证协议的区别

今天上午同事问我 rsync -av /SRC root@172.17.256.211:36000::/DEST 为何报 port 22 refused 的错误? 因为我们机器都是修改了 ssh 端口的,默认22端口是登录不上ssh的, 同事的本意是想修改...

大数据之路

2012/08/27

0

0

神奇的选择器 :focus-within

CSS 的伪类选择器和伪元素选择器,让 CSS 有了更为强大的功能。 伪类大家听的多了,伪元素可能听到的不是那么频繁,其实 CSS 对这两个是有区分的。 有个错误有必要每次讲到伪类都提一下,有时...

chokcoco

08/02

0

0

原 荐 jdk8新特性之双冒号 :: 用法及详解
【前端】你所不知的 CSS ::before 和 ::after 伪元素用法

CSS 有两个说不上常用的伪类 :before 和 :after,偶尔会被人用来添加些自定义格式什么的,但是它们的功用不仅于此。前几天发现了 Creative Link Effects 这个非常有意思的介绍创意链接特效的...

issac宝华

2016/11/01

40

0

Java8新特性(一)_interface中的static方法和default方法

为什么要单独写个Java8新特性,一个原因是我目前所在的公司用的是jdk8,并且框架中用了大量的Java8的新特性,如上篇文章写到的stream方法进行过滤map集合。stream方法就是接口Collection中的...

阳光温暖

07/31

0

0

JDK8学习笔记-Function接口

学习JDK8新特性,必不可少的就是函数式编程,那也就不得不了解Function接口的使用了。 首先看下Function接口的定义 接口定义了两个泛型,在使用的时候需要指定。 该接口中比较重要的就是这个...

十月阳光

2017/10/18

0

0

没有更多内容

加载失败,请刷新页面

加载更多
Python 从爬虫到数据分析(二)爬虫原理

接着第一部分说,爬虫就是请求网站并提取数据的自动化程序。其中请求,提取,自动化是爬虫的关键!接下来看看流程。 1.爬虫的基本流程 发起请求 通过HTTP库向目标站点发起请求,也就是发送一个...

China丶小可

22分钟前

1

0

原 荐 jdk8新特性之双冒号 :: 用法及详解
vue与react哪种好?

vue与react,到目前为止两个我都用来写了好多项目,vue用的脚手架是vue-cli,react用的是dva,两者都对其进行了很好的封装,只需要简单的几步就能跑起来. 之前在国外一大神讨论这两者之间的区域,...

前端大白

28分钟前

1

0

log4j 具体配置

log4j使用DailyRollingFileAppender DailyRollingFileAppender是日志记录软件包Log4J中的一个Appender,它能够按一定的频度滚动日志记录文件。 我们可以按下面的方式配置DailyRollingFileApp...

hotsmile

30分钟前

1

0

网络爬虫框架 Scrapy 入门教程

Scrapy 是一个用 Python 开发的爬虫框架,用于抓取 Web 页面并提取其中的结构化数据。 安装 首先,确定你的电脑上已经安装了 Python 3 以及对应的 pip。可以使用下面的命令查看: $ python3 ...

linuxprobe16

51分钟前

0

0

VUE动态绑定audio/video/img的src不能播放或显示

写个项目,要求要本地上传音视频至服务器,再回显可播放。 当前项目使用了elementUI+Vue 上传图片,请求接口,将图片或者音频文件提交给后台,后台返回存储图片或者音频的ID,因为后台存到m...

李晓艳

54分钟前

1

0

原 荐 jdk8新特性之双冒号 :: 用法及详解

没有更多内容

加载失败,请刷新页面

加载更多
原文  https://my.oschina.net/wangbo888/blog/1942354
正文到此结束
Loading...