/**
* 方法引用格式:
* 双冒号:: 引用运算符,它所在的表达式被称为方法引用。如果Lambda表达式
* 的函数方案已经存在于某个地方的实现中,
* ===》那么可以通过双冒号来引用改方法作为Lambda表达式的代替者
*/

例子:

public class Demo01Print {
private static void printString(Printable p){
p.print("quan");
} public static void main(String[] args) {
printString((s)->{
System.out.println(s);
});
/**
* 表达式的目的:打印参数传递的字符串
* 把参数s,传递给System.out对象,调用out对象的pringln方法进行输出
* System.out对象已经存在
* pringln方法已经存在
* =====》可以使用方法引用来优化表达式
* 就是使用system.out方法直接引用(调用)pringln方法。
*/
printString(System.out::println);
}

结果输出:

quan
quan

通过对象名引用成员方法

最常见的一种用法,其实就是上面的做法:

/**
* 通过对象名引用成员方法
* 前提:
* 对象名存在,方法名存在
* 就可以使用对象名来引用成员方法
*/

例子:

1先创建对象类

public class MethodRefObject {
public void pringUpperCaseString(String s){
System.out.println(s.toUpperCase());
}
}

2创建函数式接口

@FunctionalInterface
public interface Printable {
//定义字符串的抽象方法
void print(String s);
}

3测试方法:

public class Demo01MethodRefObject {
private static void pringString(Printable p){
p.print("quan");
} public static void main(String[] args) { pringString((s)->{
//创建MethodRefObject对象
MethodRefObject obj = new MethodRefObject();
//调用对象里面的成员方法pringUpperCaseString把字符
//串按照大写输出
obj.pringUpperCaseString(s);
}); //使用方法引用优化,先创建MethodObject对象
MethodRefObject obj = new MethodRefObject();
pringString(obj::pringUpperCaseString);
}
}
/**
* re:
* QUAN
* QUAN
**/

通过类名称引用静态方法

/**
* 通过类名引用静态承焰方法
* 前提:
* 类已经存在,静态成员方法存在
*
*/

例子:

public class Demo01StaticMethodReference {
//定义一个方法,方法的参数传递要计算的整数和函数式接口Calcable
private static int method(int num,Calcable c){
return c.calAbs(num);
} public static void main(String[] args) {
//调用method方法
int i =method(-10,(n)->{
//计算绝对值,使用的是Math类当中的静态方法abs
return Math.abs(n);
});
System.out.println(i); /**
*使用方法引用优化Lambda表达式
* Math类存在
* abs计算绝对值静态方法存在
*/
int i1 = method(-10,Math::abs);
System.out.println(i1);
} }

通过supper引用父类的成员方法

存在子父关系

创建一个父类

//父类
public class Human {
public void sayHello(){
System.out.println("say hello");
}
}

创建一个函数式接口

@FunctionalInterface
public interface Greetable {
void greet();
}

创建一个子类:

public class Man extends Human{
@Override
public void sayHello() {
System.out.println("hello,I'm Man");
} public void method(Greetable g){
g.greet();
} public void show(){
method(()->{
//创建父类
Human human = new Human();
human.sayHello();
});
/**
* 存在子夫类关系,存在super关键字,代表父类
* 直接通过super调用父类成员方法
*/
method(()->{
super.sayHello();
});
/**
* 通过super引用类的成员方法
*/
method(super::sayHello); } public static void main(String[] args) {
new Man().show();
new Man().sayHello();
}
}

结果:

say hello
say hello
say hello
hello,I'm Man

通过this引用成员方法

this代表当前对象,如果需要引用的方法就是当前类中的成员方法。

可以使用this::成员方法来使用方法引用

定义一个接口

@FunctionalInterface
public interface Richable {
void buy();
}
/**
* 通过this引用奔雷成员方法
*/
public class Husbard {
public void buyHome(){
System.out.println("买房子");
} public void marry(Richable r){
r.buy();
} public void soHappy(){
marry(()->{
//使用this成员方法
this.buyHome();
});
/**
* 使用方法引用优化Lambda表达式
*/
marry(this::buyHome);
} public static void main(String[] args) {
new Husbard().soHappy();
} }

类的构造器引用

构造器和类名完全一致,所以使用方式为:类名称::new的格式表示。

定义一个函数式接口

/**
* 定义一个创建Person对象的函数式接口
*/
@FunctionalInterface
public interface PersonBuilder {
//根据姓名创建Person对象返回
Person builderPerson(String name);
}

一个要被创建的类Person

public class Person {
private String name; public Person() {
} public Person(String name) {
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
/**
* 类的构造器引用
*/
public class Demo {
public static void printName(String name,PersonBuilder builder){
Person person = builder.builderPerson(name);
System.out.println(person.getName());
} public static void main(String[] args) {
printName("quan",(name)->{
return new Person(name);
});
/**
* 使用方法引用优化lambda表达
*/
printName("quan2",Person::new);
}
}
//re:quan
// quan2

数组构造器的引用

数组是Object的子类对象,同样具有构造器,但是语法不太一样

/**
* 数组的构造器引用
* 数组::new
* 例子:int[]::new
*/

创建一个接口

//创建数组的函数式接口
@FunctionalInterface
public interface ArrayBuilder {
//返回一个给定长度的int类型数组
int[] builderArray(int length);
}
public class Demo1 {
public static int[] createArray(int length,ArrayBuilder ab){
return ab.builderArray(length);
} public static void main(String[] args) {
//调用create方法,传递数组长度和表达式
int[] lenint = createArray(12,(len)->{
return new int[len];
}); System.out.println(lenint.length); //优化,int[]就是数组的构造函数名字
int[] lenint2 = createArray(15,int[]::new);
System.out.println(lenint2.length);
}
}
//re:12
// 15

java-方法引用的更多相关文章

  1. Atitit java方法引用(Method References) 与c#委托与脚本语言js的函数指针

    Atitit java方法引用(Method References) 与c#委托与脚本语言js的函数指针   1.1. java方法引用(Method References) 与c#委托与脚本语言js ...

  2. Java 方法引用_特性

    JAVA8 方法引用:(四种方法引用的使用) 对象引用的特点:不同的对象可以操作同一块的内容:而方法引用就是指为一个方法设置别名,相当于一个方法定义了不同的名字. 引用静态方法: 类名称 :: sta ...

  3. java 方法引用(method reference)

    it -> it != null等价于Objects::nonNull

  4. 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

  5. Java 8函数编程轻松入门(四)方法引用

    C#中系统提供了许多IEnumerable的扩展方法.同样在Java 8中新引入了Collector类. 1.方法引用 定义: 简而言之:就是一个Lambda表达式.在Java 8中,我们我们会使用L ...

  6. Java笔记——Java8特性之Lambda、方法引用和Streams

    Java8已经推出了好一段时间了,而掌握Java8的新特性也是必要的,如果要进行Spring开发,那么可以发现Spring的官网已经全部使用Java8来编写示例代码了,所以,不学就看不懂. 这里涉及三 ...

  7. Java 8新特性-4 方法引用

    对于引用来说我们一般都是用在对象,而对象引用的特点是:不同的引用对象可以操作同一块内容! Java 8的方法引用定义了四种格式: 引用静态方法     ClassName :: staticMetho ...

  8. JAVA 8 方法引用 - Method References

    什么是方法引用 简单地说,就是一个Lambda表达式.在Java 8中,我们会使用Lambda表达式创建匿名方法,但是有时候,我们的Lambda表达式可能仅仅调用一个已存在的方法,而不做任何其它事,对 ...

  9. [转]深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...

  10. Upgrading to Java 8——第二章 Method References(方法引用)

    概述 很多java 方法会使用函数式接口作为参数.例如,java.util.Arrays类中的一个sort方法,就接受一个Comparator接口,它就是一个函数式接口,sort方法的签名如下: pu ...

随机推荐

  1. [文档]运维故障报告template

    RCA的基本概念 根本原因分析技术(root cause analysis,RCA). IOWA州立大学质量管理学院认为,很多公司在设备发生故障后,都能够很快修复, 但难以发现故障的根本原因,所以此故 ...

  2. 【转】浅谈 Integer 类

    突然发现自己对Integer i = 10;这种语法不太明白,于是乎有了这篇文章,那么在讲解 Integer 之前,我们先看下面这段代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  3. [题解]第十一届北航程序设计竞赛预赛——F.序列

    题目描述 (1,--,n)的一个排列S,定义其对应的权值F[S]为:将S划分为若干段连续子序列,每个子序列都是上升序列,F[S]的值等于能划分出的最小段数. 求n的全排列的F[S]的和,答案mod(1 ...

  4. vue2项目,踩坑Jest单元测试

    目前的项目已经维护了挺久,由于客户要求,我们要为项目加上单元测试,挑选一番后选择了Jest(配置简便,开箱即用),下面记录了此次为项目添加Jest作为单元测试的经历. 安装Jest 1. 在项目目录下 ...

  5. python+pytest(3)-接口测试一般流程及方法

    首先我们要明确,通常所接口测试其实就属于功能测试,主要校验接口是否实现预定的功能,虽然有些情况下可能还需要对接口进行性能测试.安全性测试. 在学习接口自动化测试之前,我们先来了解手工接口测试怎样进行. ...

  6. Java、Python语法区别,不断更新

    基本语句.文件方面 Java中的字符是单引号,字符串是双引号:Python则是单双都可以 Java语句结束有分号;,Python没有(写分号也正确) Java中程序执行需要有main函数,Python ...

  7. JZ-067-剪绳子

    剪绳子 题目描述 给你一根长度为n的绳子,请把绳子剪成整数长的m段(m.n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],...,k[m]. 请问k[1]x... ...

  8. ELK日志收集(SpringBoot)

    目录 环境&准备 ES安装 Kibana安装 Logstash安装 Logstash配置 SpringBoot中logback-spring.xml配置 测试 启动 ES\Kibana\Log ...

  9. javascript订阅模式浅析和基础实例

    前言 最近在开发redux或者vux的时候,状态管理当中的createStore,以及我们在组件中调用的dispatch传递消息给状态管理中心,去处理一些操作的时候,有些类似我们常见到订阅模式 于是写 ...

  10. think php 登录日记

    */ public function save(Request $request) { // $params = $request->param(); $file = $request-> ...