关于Lambda表达式的方法引用和构造器引用简的单示例

 更新时间:2023年04月06日 10:38:21   作者:CrazyDragon_King  
这篇文章主要介绍了关于Lambda表达式的方法引用和构造器引用简的单示例,方法引用与构造器引用可以使 Lambda 表达式的代码块更加简洁<BR>,需要的朋友可以参考下

方法引用和构造器引用

了解了 Lambda 表达式有一段时间了,但是都没有怎么练习,一直停留在最低层次的了解程度,这对于追求技术进步的人来说确实不是太好,所以就来继续深入学习以下。

使用要求:

如果Lambda表达式的代码块只有一条代码,程序就可以省略 Lambda 表达式中的代码块和花括号,还可以使用方法引用与构造器引用

作用:

方法引用与构造器引用可以使 Lambda 表达式的代码块更加简洁(可能代码越短越好吧!)

使用:

方法引用与构造器引用都需要使用两个冒号::

Lambda支持的方法引用和构造器引用

种类示例说明
引用类方法Integer::valueOf函数式接口中被实现方法的全部参数传给该类方法作为参数
引用特定对象的实例方法System.out::println函数式接口中被实现方法的全部参数传给该方法作为参数
引用某类对象的实例方法

System.out::println

函数式接口中被实现方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数
引用构造器Dog::new函数式接口中被实现方法的全部参数传给该构造器作为参数

代码:

定义需要使用的函数式接口

@FunctionalInterface
interface Instance<E>{
	E get(String name, int age);
}

@FunctionalInterface
interface Converter{
	Integer converter(String age);
}

@FunctionalInterface
interface Say{
	String say(Dog dog, String hobby);
}

定义一个 Dog 类,作为示例使用

class Dog{
	private String name;
	private int age;
	
	public Dog(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public void grow(Converter con, String age) {
		this.age = con.converter(age);
	}
	
	public int getNameLength(String name) {
		return name.length();
	}
	
	public String hobby(String hobby) {
		return this.toString()+" I love "+hobby;
	}

	@Override
	public String toString() {
		return "Dog [name=" + name + ", age=" + age + "]";
	}
}

测试代码

我把没有使用方法引用和构造器引用的代码注释了,并且就放在 Lambda 表达式上面,用作对比参考。

public class Client {
	public static void main(String[] args) {
		//使用方法引用和构造器引用使得 Lambda 表达式更加简洁
		/*
		 * 1.引用构造器
		 * */
		//Instance<Dog> instance1 = (name, age)->new Dog(name,age);
		Instance<Dog> instance = Dog::new;
		Dog dog = instance.get("小黑", 12);
		String str = dog.toString();
		System.out.println(str);
		
		/*
		 * 2.引用类方法
		 * */
		//Converter converter1 = age->Integer.valueOf(age);
		Converter converter1 = Integer::valueOf;
		dog.grow(converter1,"18");
		System.out.println(dog.toString());
		
		/*
		 * 3.引用特定对象的实例方法
		 * */
		//Converter converter2 = name->dog.getNameLength(name);	
		Converter converter2 = dog::getNameLength;
		int len = converter2.converter(dog.getName());
		System.out.println("dog 的名字有:"+len+" 个字符!");
		
		/*
		 * 4.引用某类对象的实例方法
		 * */
		//Say say1 = (dog1,hobby)->dog1.hobby(hobby);
		Say dogSay = Dog::hobby;
		String str1 = dogSay.say(dog, "running!");
		System.out.println(str1);
	}
}

运行截图

测试结果

学以致用
学习是为了更好的理解,下面来举一个简单的例子,来看看这个的应用。
**忽略这里的 Comparable接口 **

public class Dog implements Comparable<Dog>{
	private String name;
	private int age;
	
	public Dog(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public int getAge() {
		return age;
	}
	
	@Override
	public int compareTo(Dog dog) {
		return this.age > dog.age ? 1 : this.age < dog.age ? -1 : 0;
	}
	
	@Override
	public String toString() {
		return "Dog [name=" + name + ", age=" + age + "]";
	}
}

测试代码

public class ClientTest {
	public static void main(String[] args) {
		LinkedList<Dog> list = new LinkedList<>();
		list.add(new Dog("大黄",12));
		list.add(new Dog("小黑",13));
		list.add(new Dog("二哈",11));
		list.add(new Dog("小白",9));
		list.add(new Dog("旺财",8));
		
		//引用特定对象的实例方法
		Consumer<Dog> consumer = System.out::println;  
		list.forEach(consumer);    
		
		System.out.println("-------模拟上面的 foreach 方法-----------");
		Consumer<Dog> con = dog->System.out.println(dog);
		for (Dog dog : list ) {
			con.accept(dog);
		}
	}
}

说明
注意上面那个方法list.forEach(consumer);
这个方法的参数是一个函数式接口对象,就是传入一个 lambda 表达式,它本身是使用了 方法引用(引用特定对象的方法 System.outPrintStream 的对象),但是为什么传入一个 接口对象就能实现打印输出(也可以根据自己写的 Lambda 表达式 完成具体功能)?
保持对问题的好奇心,可以思考以下,下面是我模拟的结果,因为最终要完成还是需要借助于方法来进行的,可以打开 Consumer 接口,里面只有一个 accept 方法,很容易就能想到,借助 foreach 循环进行遍历操作。
我们查看 list.forEach 的 API 就能看出来,实现大致如此,只不过加了一个null值处理。

运行结果:

运行结果

总结

Lambda 作为 Java8 的新特性,值得了解一下,函数式编程和我们以前接触的命令式编程还是有区别的。这里简单了解了一下方法引用和构造器引用。
方法引用和构造器引用可以使得代码更加简洁,易于理解,非常符合函数式编程的特性,这里涉及的知识不是很难,可以了解一下。
最后以一个常见的小例子来进一步理解 lambda 表达式。

到此这篇关于关于Lambda表达式的方法引用和构造器引用简的单示例的文章就介绍到这了,更多相关Lambda方法引用和构造器引用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java工具类之实现java获取文件行数

    java工具类之实现java获取文件行数

    这篇文章主要介绍了一个java工具类,可以取得当前项目中所有java文件总行数,代码行数,注释行数,空白行数,需要的朋友可以参考下
    2014-03-03
  • 解决springdataJPA对原生sql支持的问题

    解决springdataJPA对原生sql支持的问题

    这篇文章主要介绍了解决springdataJPA对原生sql支持的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • spring+springmvc+mybatis+maven入门实战(超详细教程)

    spring+springmvc+mybatis+maven入门实战(超详细教程)

    这篇文章主要介绍了spring+springmvc+mybatis+maven入门实战(超详细教程),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • 深入理解Java之HashMap源码剖析

    深入理解Java之HashMap源码剖析

    这篇文章主要介绍了深入理解Java之HashMap源码剖析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Java 深入浅出讲解泛型与包装类

    Java 深入浅出讲解泛型与包装类

    泛型是在Java SE 1.5引入的的新特性,本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法,本篇我们一起来学习泛型以及包装类
    2022-04-04
  • Java基于TCP方式的二进制文件传输

    Java基于TCP方式的二进制文件传输

    这篇文章主要为大家介绍了Java基于TCP方式的二进制文件传输,一个基于Java Socket协议之上文件传输的完整示例,基于TCP通信完成,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • 详解如何在Spring Boot项目使用参数校验

    详解如何在Spring Boot项目使用参数校验

    本篇文章主要介绍了如何在Spring Boot项目使用参数校验,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Java生成随机数的2种示例方法代码

    Java生成随机数的2种示例方法代码

    在Java中,生成随机数有两种方法。1是使用Random类。2是使用Math类中的random方法。看下面的例子使用吧
    2013-11-11
  • ActiveMQ消息签收机制代码实例详解

    ActiveMQ消息签收机制代码实例详解

    这篇文章主要介绍了ActiveMQ消息签收机制代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Spring整合Junit的使用详解

    Spring整合Junit的使用详解

    这篇文章主要介绍了Spring整合Junit的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02

最新评论