jdk8新特性之双冒号 :: 用法及详解
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新特性之双冒号 :: 用法及详解的更多相关文章
- Java 8新特性探究(五)Base64详解
BASE64 编码是一种常用的字符编码,在很多地方都会用到.但base64不是安全领域下的加密解密算法.能起到安全作用的效果很差,而且很容易破解,他核心作用应该是传输数据的正确性,有些网关或系统只能使 ...
- ES6新特性三: Generator(生成器)函数详解
本文实例讲述了ES6新特性三: Generator(生成器)函数.分享给大家供大家参考,具体如下: 1. 简介 ① 理解:可以把它理解成一个函数的内部状态的遍历器,每调用一次,函数的内部状态发生一次改 ...
- Servlet3.0新特性WebFilter(Annotation Filter)详解
摘要: Servlet3.0作为J2EE 6规范一部分,并随J2EE6一起发布,WeFilter是过滤器注解,是Servlet3.0的新特性,不需要在web.xml进行配置,简化了配置. Name T ...
- Java 8新特性探究(十一)Base64详解
开发十年,就只剩下这套架构体系了! >>> BASE64 编码是一种常用的字符编码,在很多地方都会用到.但base64不是安全领域下的加密解密算法.能起到安全作用的效果很差,而且 ...
- jdk8新特性表达式1
Jdk8中有好多新的特性,比如引入Lambda,简化代码的书写等等 我们先看一个关于Lambda的使用 /*** 输出list */@Testpublic void test() { String[] ...
- jdk8新特性-stream
一.什么是流stream 1.可理解为高级版本的 Iterator 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的. 2.单向,不可往复 数据只能遍历一次,遍历过一次后即用尽了,就好比 ...
- 一次电话Java面试的问题总结(JDK8新特性、哈希冲突、HashMap原理、线程安全、Linux查询命令、Hadoop节点)
面试涉及问题含有: Java JDK8新特性 集合(哈希冲突.HashMap的原理.自动排序的集合TreeSet) 多线程安全问题 String和StringBuffer JVM 原理.运行流程.内部 ...
- JDK8新特性关于Stream流
在Java1.8之前还没有stream流式算法的时候,我们要是在一个放有多个User对象的list集合中,将每个User对象的主键ID取出,组合成一个新的集合,首先想到的肯定是遍历,如下: 1 2 3 ...
- java进阶一之jdk8新特性
1.官方发布的jdk8新特性 2.51CTO相关专题
随机推荐
- 修改vue的配置项支持生产环境下二级目录访问的方法
本文主要记录如何配置vue的打包文件配置项,使打包后的文件可以支持二级目录的访问. 1.常规打包 在实际的项目中,我们通常都使用 npm run build 直接打包文件后丢到服务器上访问 打包后的文 ...
- iview框架modal中嵌套modal
modal的使用是平级的,后面的会覆盖前面,如下<modal>111</modal><modal>222</modal>内容为222的弹框会在内容为11 ...
- Perl学习笔记(1)----入门
在UNIX/Linux 系统上,打开命令终端,输入 'rpm -q perl' 查看系统是否安装了 perl ---- 在自己的CentOS7 系统上,默认自带了 perl 软件: root@javi ...
- Windows操作系统----锁住命令行窗口
第一步: 新建一个.txt文档,输入如下内容: @echo off echo. setlocal :checkpassword set /p password=请输入密码: if "%pas ...
- memset用法详解
原文:http://www.cnblogs.com/PegasusWang/archive/2013/01/20/2868824.html 1.void *memset(void *s,int c,s ...
- 浅谈回归(二)——Regression 之历史错误翻译
我很好奇这个问题,于是搜了一下.我发现 Regression 这个词 本意里有"衰退"的意思. 词根词缀: re- 回 , 向后 + -gress- 步 , 级 + -ion 名词 ...
- Java数字和字符串的相互转换(BigDecimal的使用)
String s = "100."; double d1 = "1.23"; double d = Double.parseDouble(s); s = Str ...
- 阿里云安装jdk报错gzip: stdin: unexpected end of file
在阿里云上面安装jdk时候报了这个问题,如下图所示 然后看了下jdk应该是有150多M的,但是阿里云上面的只有1M多,删除 重新下载... tar zxvf jdk 好了
- ubuntu14.04server版安装redis
此博客记录首次在ubuntu14.04上安装redis过程. 以下采用两种方式进行安装 方法一:进入redis的官网下载(地址:https://redis.io/download)目前版本为4.0.9 ...
- 设计模式:备忘录(Memento)模式
设计模式:备忘录(Memento)模式 一.前言 备忘录模式用于保存和恢复对象的状态,相信大家看过我前面的拙作就会想到原型模式也能保存一个对象在某一个时刻的状态,那么两者有何不同的呢?原型模式保存 ...