java【方法引用】

方法引用

接上上一个文章,继续讲解关函数式编程中方法引用

对于一个函数式 lambda 表达式,举个栗子

对于一个 lambda 表达式,等式的左边为参数,等式的右边为执行体,执行体方法的参数就是左边的参数话,就可以使用方法引用。
Consumer<String> consumer = i ->System.out.println(i);
consumer.accept("hax");
可以写成:
Consumer<String> consumer2 = System.out::println;
consumer2.accept("hax2");

分别是包含了

静态方法引用

非静态方法引用

需要注意的第二种写法解释:静态方法与非静态方法的,在非静态方法中可以使用 this,当前的对象,而在 static 中无法使用,主要的区别是在在于非静态方法中默认给了在第一个参数的位置给了当前对象,可以写成

public person  setPerson(person this,String name) {
		this.name = name;
		return this;
}

所以我们也可以通过静态的方式进行引用,加上当前的 this,就可以了,例如第二种写法。

扩展:

使用非静态方法的时候,例如 set 和 get,一个提供者,一个消费者

在我们日常的开发中,可以会使用到类似下面的代码

List<person> arrList = new ArrayList<person>();
		//lambda表达式
		List<String> collect = arrList.stream().map(mapper->mapper.getName()).collect(Collectors.toList());
	
		//方法引用写法
		List<String> collect2 = arrList.stream().map(person::getName).collect(Collectors.toList());

1619407857801.png

无参数构造引用

有参数构造引用

下面代码进行展示

class person{

	private String name;
	private char sex;
	private Integer age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public person(String name, char sex, Integer age) {
		super();
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	public person(String name) {
		super();
		this.name = name;
	}
	public person() {
		super();
	}

	public static void  getperson(String name) {
		System.out.println(name);;
	}

	public person  setPerson(String name) {
		this.name = name;
	
		return this;
	}

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

public class function04 {

	@Test
	public void test01() {
	
		Consumer<String> consumer =  i ->System.out.println(i);
	
		Consumer<String> consumer2 =  System.out::println;
	
		consumer.accept("hax");
	
		consumer2.accept("hax2");
	
		//静态方法使用
		Consumer<String> consumer3 = person::getperson;
		consumer3.accept("静态方法使用");
	
		//非静态方法
		person per = new person();
		Function<String,person> function = per::setPerson;
		System.out.println(function.apply("非静态方法的调用"));;
	
		//非静态方法第二种写法--使用类名方式
		BiFunction<person,String,person> binBiFunction = person::setPerson;
		binBiFunction.apply(per,"非静态方法的调用");
	
		//无参数构造方法--明显就一个提供者
		Supplier<person> supplier = person::new;
		System.out.println(supplier.get());
	
		//有参数构造方法
		Function<String,person> function2 = person::new;
		System.out.println(function2.apply("构造方法"));
	
	
	}
}

类型推断

其中的 test02,为类型的推断一个案例,自定义一个函数接口进行调用实现,这样写的好处是可以调用同一个公共的操作,根据执行体的不通从而可以实现不通的操作效果。

test01 案例是表示对于 java 语言 变量引用,参数的传递是传递的值,而不是地址,这也是为什么在 java 中对于内部类参数的传递中,传递的参数必须使用 final 修饰,jdk1.8 以后只是省略了 final 修饰符,但是内容依然不可以修改的,主要原因也是 java 传递的是值,如果外部的值地址修改了,而内部值地址没有变,会造成不二性质。所以必须使用 final

package com.hax.fuction;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;

@FunctionalInterface
interface FunctionPerson{

	List<String> filterperson(List<Person> person);
}

enum  sex{
	MALE,//男
	GIRL//女
}

class Person{

private String name;

	private sex sex;

	private Integer age;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	public Person() {
		super();
	}
	public sex getSex() {
		return sex;
	}

	public void setSex(sex sex) {
		this.sex = sex;
	}

	public Person(String name, com.hax.fuction.sex sex, Integer age) {
		super();
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
	}
}


public class function05 {

	@Test
	public void Test01() {
	
		List<String> list = new ArrayList<String>();
		list.add("1");
		this.testnull(list);
	
		System.out.println(list);
	
	}

	private void testnull(List<String> list) {
		list = null;
	}
	/**
	 * 写一个类型推断操作 
	 */
	@Test
	public void test02() {
		
		/**
		 * 实现业务为:将查到的人数据为年龄大于20岁,并且为男的姓名人查询出来
		 *假设这个地方为service的业务类型
		 */
	
		String string = this.dist(personList ->personList.stream()
				.filter(person ->person.getAge()> 20 && sex.MALE.compareTo(person.getSex())==0
						).map(Person::getName).collect(Collectors.toList()));
	
		System.out.println(string);
	}

	/**
	 * 假设这个为持久层业务
	 * @param funcPerson 自定义的函数类型
	 * @return
	 */
	private String dist(FunctionPerson funcPerson) {
		/*
		 * 假设这里是从数据库中查询到数据
		 */
		List<Person> perList =new ArrayList<Person>();
	
		perList.add(new Person("hax01",sex.MALE,18));
		perList.add(new Person("hax02",sex.MALE,28));
		perList.add(new Person("hax03",sex.MALE,38));
		perList.add(new Person("hax04",sex.GIRL,48));
	
		return funcPerson.filterperson(perList).toString();
	}
}

级联表达式

@Test
	public void test01() {
	
		Function<Integer, Function<Integer, Function<Integer, Integer>>> function = x->y->z->x+y+z;
		
System.out.println(String.format("【级联输出】%s",function.apply(1).apply(2).apply(3)));
	
	}

方法返回方法,进行输出累加操作。

  • lam
    1 引用
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    2920 引用 • 8120 回帖 • 671 关注
  • 方法引用
    2 引用

广告 我要投放

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...