/**
* 方法引用格式:
* 双冒号:: 引用运算符,它所在的表达式被称为方法引用。如果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. java8 如何优化CAS的性能

    场景引入 经常都会有下面这段代码,多个线程同时修改一个变量,造成线程不安全,代码如下: public class ThreadCASDemo implements Runnable { static ...

  2. PostgreSQL-PL/pgSQL控制结构

    PL/pgSQL的控制结构是最重要及最有用的一部分了,在实际工作场景都离不开业务处理逻辑,在写PL/pgSQL时,利用控制结构来操作数据.PL/pgSQL支持的控制结构与其他语言几乎差不多,比如:条件 ...

  3. mapreduce类型对应

    public class OrderBean implements WritableComparable<OrderBean> { private Integer order_id; // ...

  4. JavaSE高级编程之多线程

    4. 多线程 4.1 基本概念:程序.进程和线程 程序.进程和线程 程序:为了完成特定的任务,用某种语言编写的一组指令的集合.程序是一段静态的代码,静态对象. 进程:是程序的一次执行过程或正在运行的程 ...

  5. Windows运行(Win+R)快速启动所有程序(自定义)

    运行Win+R我们都会用,等同于开始菜单的"运行".注意,只是效果等同, 从速度来看,按win+r比用鼠标要快很多倍.用win+r启动常用程序 最常用的是输入cmd打开命令行或ca ...

  6. Python回顾笔记(此讲大致说明,详情请看之前的笔记)

    内容概要 数据分析(numpy,pandas,matplib) 数据清洗 爬虫 teableau软件 今日内容概要 Python知识回顾 数据分析 ipython模块 anaconda软件 numpy ...

  7. Python程序基本知识

    Python程序基本知识 一. 数据类型与变量 1.1 变量 **变量:**在Python中不需要事先声明变量名及其类型,直接赋值即可创建各种类型的变量 x='Hello World' #创建了整型变 ...

  8. GPT-3被超越?解读低能耗、高性能的GlaM模型

    原创作者 | LJ GLaM: Efficient Scaling of Language Models with Mixture-of-Experts https://arxiv.org/pdf/2 ...

  9. C#实现抢红包算法

    二倍均值法(公平版) 发出一个固定金额的红包,由若干个人来抢,需要满足哪些规则? 1.所有人抢到金额之和等于红包金额,不能超过,也不能少于. 2.每个人至少抢到一分钱. 3.要保证所有人抢到金额的几率 ...

  10. git flow 工作流程以及常用命令

    一.分支介绍 master 也是产品分支,只有一个,一般情况下不会在这个分支上进行代码操作 develop 只有一个,新特性的开发是基于 develop 开发的,但是不能直接在 develop 上进行 ...