文档章节

一起来学Java8(三)——方法引用

猿敲月下码
 猿敲月下码
发布于 10/22 12:30
字数 877
阅读 73
收藏 3

一起来学Java8(一)——函数式编程中有一个简单的函数式编程的例子:

import java.util.function.Consumer;

class Person {
    public static void sayHello(String name) {
        System.out.println("hello " + name);
    }
}

public class TestPerson {

	public static void main(String[] args) {
		work(Person::sayHello); // hello Jim
	}
	
	public static void work(Consumer<String> consumer) {
		consumer.accept("Jim");
	}
}

其中Person::sayHello被称为方法引用,方法引用可以用Lambda表达式来代替,代码如下:

public static void main(String[] args) {
	work((name) -> {
		System.out.println("hello " + name);
	}); // hello Jim
}

方法引用和Lambda关系

方法引用和Lambda表达式之间有什么关系呢?

方法引用可以看做是Lambda表达式的一种快捷方式。这种快捷方式是建立在某种条件之上的,大致可以分为三类:

  1. 静态方法引用
  2. 自身类型方法引用
  3. 现有实例方法引用

静态方法引用

上面提到的例子就是静态方法引用,我们还可以使用其它静态方法来替代

public static void main(String[] args) {
	work(String::toString);
	work(String::toLowerCase);
}

可以看到,Lambda表达式有一个参数(String name),String.toString和String.toLowerCase和Person.sayHello也是同样的参数类型, 只要是参数签名一致都可以替换使用。

自身类型方法引用

当Lambda表达式的方法体内直接使用参数中的对象方法,可以使用这种方式。比如下面这个例子:

public static void main(String[] args) {
	// 方式1,使用Lambda表达式
	print("hello", (String s) -> s.toLowerCase());
	// 方式2,使用方法引用
	print("hello", String::toLowerCase);
}

private static void print(String argu, Consumer<String> consumer) {
	consumer.accept(argu);
}

Lambada表达式中有个参数(String s) 在方法体中直接使用了参数对象中的方法 s.toLowerCase(),因此可以简写为:String::toLowerCase

在来一个复杂点的例子:

package learn.java8.ch3;

import java.util.function.Function;

class Goods {
	private int price;

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}
}

class GoodsService {
	private Goods goods;

	public GoodsService(Goods goods) {
		super();
		this.goods = goods;
	}

	public void showPrice(Function<Goods, Integer> fun) {
		int price = fun.apply(goods);
		System.out.println("商品价格:" + price);
	}
}

public class TestPerson2 {

	public static void main(String[] args) {
		Goods goodsApple = new Goods();
		goodsApple.setPrice(100);

		GoodsService service = new GoodsService(goodsApple);
		// 方式1,使用Lambda表达式
		service.showPrice((Goods goods) -> {
			return goods.getPrice();
		});
		
		// 方式2,使用方法引用
		service.showPrice(Goods::getPrice);
	}

}

方式1中有个Lambda表达式,参数为Goods goods,在方法体中又直接调用了goods对象的getPrice,因此可以简化为:service.showPrice(Goods::getPrice);

现有实例方法引用

当Lambda表达式的方法体内没有使用参数中的对象方法,使用了其它对象的方法。比如下面这个例子

package learn.java8.ch3;

import java.util.function.Consumer;

class Dog {
	private int age;

	public Dog(int age) {
		super();
		this.age = age;
	}

	public void say(String name) {
		System.out.println("dog age is " + age + ", dog name is " + name);
	}
}

public class TestPerson4 {

	public static void main(String[] args) {
		Dog dog = new Dog(3);
		// 方式1,使用Lambda表达式
		print("Tom", (String s) -> dog.say(s));
		// 方式2,实例对象方法引用
		print("Tom", dog::say);
	}

	private static void print(String argu, Consumer<String> consumer) {
		consumer.accept(argu);
	}

}

第二种跟第三种的区别就是,Lambda方法体中有没有直接使用Lambda参数中的方法。

下面总结一下Lambda表达式和方法引用的等价关系:

  • (Dog dog) -> dog.getAge() 等价于 Dog::getAge
  • () -> XXClass.run() 等价于 XXClass::run
  • (dog, name) -> dog.say(name) 等价于 Dog::say
  • (name) -> dog.say(name) 等价于 dog::say

小结

本篇主要介绍了方法引用,并分别演示了三种不同的方法引用。

定期分享技术干货,一起学习,一起进步!

© 著作权归作者所有

猿敲月下码

猿敲月下码

粉丝 49
博文 36
码字总数 34448
作品 4
杭州
高级程序员
私信 提问
【java8】java新特性(一)——全局观

一、前言 年前的时候 ,我一个师姐出去工作,被鄙视了。说写的代码太垃圾。当时我也没有在意,回头想想自己,本以为自己写的代码天衣无缝,无可挑剔。但是自从自己遇到了Java8 后,我的世界观...

kisscatforever
2018/03/15
0
0
一起来学Java8(一)——函数式编程

在这篇文章中,我们将了解到在Java8下如何进行函数式编程。 函数式编程 所谓的函数式编程就是把函数名字当做值进行传递,然后接收方拿到这个函数名进行调用。 首先来看下JavaScript如何进行函...

tanghc
10/19
48
0
Java中的接口Interface是不是继承自Object?+ 复习基本概念

概要 今天遇见一个严肃的问题,说出大家看看, Java中的接口Interface是不是继承自Object? 下面一起来看看吧! interface是继承自Object? 开门见山得回答——不是 引用自 《The Java Langua...

xidiancoder
2017/09/17
0
0
第一章 为什么要关心java8

一、java怎么还在变 1、java在编程语言生态系统中的位置 java虚拟机(JVM)及其字节码可能会变得比java语言本身更重要,而且对于某些应用来说,java可能会被同样运行在JVM上的竞争对手(如S...

一个yuanbeth
2018/09/25
38
0
【java8】java新特性(三)——方法引用

一、前言 之前的文章解释了Java8的Lambda表达式。今天小编继续向大家介绍一下——方法引用。 二、通过lambda表达式引出方法引用 在我们使用Lambda表达式的时候,我们通常使用lambda表达式来创...

kisscatforever
2018/03/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

BigDecimal 去后面无用的0的方法

BigDecimal a=new BigDecimal("0.1000"); System.out.println(a.stripTrailingZeros().toPlainString());...

xiaodong16
16分钟前
4
0
JAVA--高级基础开发

[集合版双色球] 十二、双色球规则:双色球每注投注号码由6个红色球号码和1个蓝色球号码组成。红色球号码从1—33中选择;蓝色球号码从1—16中选择;请随机生成一注双色球号码。(要求同色号码...

李文杰-yaya
昨天
14
0
聊聊rocketmq broker的CONSUMER_SEND_MSG_BACK

序 本文主要研究一下rocketmq broker的CONSUMER_SEND_MSG_BACK CONSUMER_SEND_MSG_BACK rocketmq/common/src/main/java/org/apache/rocketmq/common/protocol/RequestCode.java public class......

go4it
昨天
3
0
API常见接口(下)

system类 StringBuilder和StringBuffer 包装类 1.System类 (java.lang包中) 提供了大量的静态方法,可以获取与系统相关的信息或系统级操作。 常用方法: public static long currentTimeMi...

Firefly-
昨天
4
0
MySQL系列:一句SQL,MySQL是怎么工作的?

对于MySQL而言,其实分为客户端与服务端。 服务端,就是MySQL应用,当我们使用net start mysql命令启动的服务,其实就是启动了MySQL的服务端。 客户端,负责发送请求到服务端并从服务端获取数...

杨小格子
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部