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新特性之双冒号 :: 用法及详解的更多相关文章

  1. Java 8新特性探究(五)Base64详解

    BASE64 编码是一种常用的字符编码,在很多地方都会用到.但base64不是安全领域下的加密解密算法.能起到安全作用的效果很差,而且很容易破解,他核心作用应该是传输数据的正确性,有些网关或系统只能使 ...

  2. ES6新特性三: Generator(生成器)函数详解

    本文实例讲述了ES6新特性三: Generator(生成器)函数.分享给大家供大家参考,具体如下: 1. 简介 ① 理解:可以把它理解成一个函数的内部状态的遍历器,每调用一次,函数的内部状态发生一次改 ...

  3. Servlet3.0新特性WebFilter(Annotation Filter)详解

    摘要: Servlet3.0作为J2EE 6规范一部分,并随J2EE6一起发布,WeFilter是过滤器注解,是Servlet3.0的新特性,不需要在web.xml进行配置,简化了配置. Name T ...

  4. Java 8新特性探究(十一)Base64详解

    开发十年,就只剩下这套架构体系了! >>>   BASE64 编码是一种常用的字符编码,在很多地方都会用到.但base64不是安全领域下的加密解密算法.能起到安全作用的效果很差,而且 ...

  5. jdk8新特性表达式1

    Jdk8中有好多新的特性,比如引入Lambda,简化代码的书写等等 我们先看一个关于Lambda的使用 /*** 输出list */@Testpublic void test() { String[] ...

  6. jdk8新特性-stream

    一.什么是流stream 1.可理解为高级版本的 Iterator 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的. 2.单向,不可往复 数据只能遍历一次,遍历过一次后即用尽了,就好比 ...

  7. 一次电话Java面试的问题总结(JDK8新特性、哈希冲突、HashMap原理、线程安全、Linux查询命令、Hadoop节点)

    面试涉及问题含有: Java JDK8新特性 集合(哈希冲突.HashMap的原理.自动排序的集合TreeSet) 多线程安全问题 String和StringBuffer JVM 原理.运行流程.内部 ...

  8. JDK8新特性关于Stream流

    在Java1.8之前还没有stream流式算法的时候,我们要是在一个放有多个User对象的list集合中,将每个User对象的主键ID取出,组合成一个新的集合,首先想到的肯定是遍历,如下: 1 2 3 ...

  9. java进阶一之jdk8新特性

    1.官方发布的jdk8新特性 2.51CTO相关专题

随机推荐

  1. DOM Tree

    DOM Tree   什么是DOM树:网页的所有内容在内存当中,其实是以树形结构存储的 何时创建:当浏览器,读取html中内容的时候,会马上开始创建DOM树. 如何创建: 1.读到HTML的时候还没有 ...

  2. log在无法调试代码时的妙用

    1. 如果修改源代码 通过加入log打印日志 可以判断程序走的流程 找到需要自定义修改的位置(如修改java编写的项目 ApacheDS ) 2. 如果java调用dll文件 出错了 排错的方式也可以 ...

  3. SSIS 和 SSRS自制Template

    可以使用VS 制作一个SSIS 的Package. 路径:C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssembl ...

  4. 通过JTS源码分析Rtree(未完待续)

    前言 R树在数据库等领域做出的功绩是非常显著的.它很好的解决了在高维空间搜索等问题.它把B树的思想很好的扩展到了多维空间,采用了B树分割空间的思想,并在添加.删除操作时采用合并.分解结点的方法,保证树 ...

  5. python SQLAchemy多外键关联

    关联同一张表的两个字段 Customer表有2个字段都关联了Address表 创建表结构 orm_many_fk.py 只创建表结构 from sqlalchemy import Integer, F ...

  6. AMD,CMD,UMD 三种模块规范 写法格式

    一下三块均以 foo.js 为示例文件名,以 jQuery,underscore 为需求组件 ADM:异步模块规范, RequireJs 的支持格式 // 文件名: foo.js define(['j ...

  7. angularJS web应用SEO

    javascript给网站带来丰富的用户体验,越来越多的网站开始应用angularjs/emberjs这类MVC来开发web应用,可以说能够使用native方式来看法的手机app基本都可以使用替代的j ...

  8. sql server中同时执行select和update语句死锁问题

    原始出处 http://oecpby.blog.51cto.com/2203338/457054 最近在项目中使用SqlServer的时候发现在高并发情况下,频繁更新和频繁查询引发死锁.通常我们知道如 ...

  9. MVC中重定向几种方法

    //1.Response.Redirect using System; using System.Collections.Generic; using System.Linq; using Syste ...

  10. centos无法用password登录,只能用public key的解决办法

    如上图只能用public key登录,只是我在17年申请的阿里云免费体验半年的服务器上遇到的, 那么我们用阿里云后台的远程连接按钮进入服务器,进入后 就看/etc/ssh/sshd_config文件配 ...