JAVA进阶 —— 方法引用

目录

一、 内容概述 

 二、方法引用的分类

 1.  引用静态方法

2.  引用成员方法

2.1 引用其他类的成员方法

2.2  引用本类或父类的成员方法

3. 引用构造方法

4. 其他调用方法

4.1  类名引用成员方法

4.2  引用数组的构造方法

三、 方法引用综合小练习

1. 转为自定义对象并且收集到数组

2. 获取部分属性并收集到数组


一、 内容概述 

方法引用可以拆分为方法和引用两方面:

JAVA进阶 —— 方法引用_第1张图片

方法引用:把已经有的方法拿过来用,当作函数接口中抽象方法的方法体。

:: (方法引用符)

JAVA进阶 —— 方法引用_第2张图片
JAVA进阶 —— 方法引用_第3张图片

但是要注意: 并不是所有的方法都可以直接引用,需要满足以下四种条件

  • 引用处必须是函数式接口
  • 被引用的方法必须已经存在
  • 被引用方法的形参和返回值必须和抽象方法保持一致
  • 被引用方法的功能要满足当前需求
public class FunctionDemo {
	public static void main(String[] args) {
		// 需求: 床技术组,进行倒序排列
		Integer[] arr = { 3, 5, 4, 1, 6, 2 };
		// 通过层层递进 进一步学习方法引用

		//匿名内部类
		Arrays.sort(arr, new Comparator() {
			@Override
			public int compare(Integer o1,Integer o2) {
				return o2 -o1;
			}
		});
		System.out.println(Arrays.toString(arr));
		
		//lambda表达式
		//因为第二个参数的类型Comparator是一个函数式接口
		Arrays.sort(arr, (Integer o1,Integer o2) -> {
			return o2 - o1;
		});
				
		//lambda表达式简化格式
		Arrays.sort(arr, (o1,o2) -> o2 - o1);

		//方法引用
		//1.引用处必须是函数式接口
		//2.被引用的方法必须已经存在
		//3.被引用方法的形参和返回值必须和抽象方法保持一致
		//4.被引用方法的功能要满足当前需求
		
		//表示引用FunctionDemo中的substraction方法
		//把这个方法当作抽象方法的方法体
		Arrays.sort(arr, FunctionDemo::subStraction);
		System.out.println(Arrays.toString(arr));
		
	}
	//可以使Java已经写好的 ,也可以是一些第三方工具类
	//静态方法 类名调用
	public static int subStraction(int num1,int num2) {
		return num2 - num1 ;
	}
}

 二、方法引用的分类

JAVA进阶 —— 方法引用_第4张图片

 1.  引用静态方法

格式: 类名: : 静态方法

范例: Integer: : parseInt

public class FunctionTest {
	public static void main(String[] args) {
		//1.创建集合并添加对象
		ArrayList list = new ArrayList<>();
		Collections.addAll(list, "1","2","3","4","5");
		
		//2.转变成int类型
		list.stream().map(new Function() {
			@Override
			public Integer apply(String s) {
				return Integer.parseInt(s);
			}
		}).forEach(s -> System.out.println(s));
		
		//1.方法需要已经存在
		//2.方法的形参和返回值需要和抽象方法的形参和返回值保持一致
		//3.方法的功能需要把形参的字符串转换为整数
		
		//方法引用
		list.stream()
		.map(Integer::parseInt)
		.forEach(s -> System.out.println(s));
	}
}

2.  引用成员方法

格式:对象: :成员方法

  1. 其他类:其他类对象: :方法名
  2. 本类:this: :方法名
  3. 父类:super: :方法名

2.1 引用其他类的成员方法

其他类:其他类对象: :方法名

// 其他类:StringOperation.java
public class StringOperation {
	public boolean StringJudge(String s) {
		return s.startsWith("张") && s.length() == 3;
	}
}


public class FunctionTest {
	public static void main(String[] args) {
		//1.创建集合
		ArrayList list =new ArrayList<>();
		//2.添加数据
		Collections.addAll(list, "张大三","李四","王五","赵六","张七");
		
		//3.过滤数据
		list.stream().filter(s->s.startsWith("张"))
		.filter(s->s.length() == 3 )
		.forEach(s->System.out.println(s)); //张大三

		//lambda表达式
		list.stream().filter(new Predicate() {
			@Override
			public boolean test(String s) {
			return	s.startsWith("张") && s.length() == 3;
			}
		}).forEach(s->System.out.println(s));
		
		//4.方法引用
		StringOperation so = new StringOperation();
		list.stream().filter(so::StringJudge)
		.forEach(s->System.out.println(s));
	}
}

2.2  引用本类或父类的成员方法

本类:this: :方法名

父类:super: :方法名

注意:引用处不能是静态方法

3. 引用构造方法

格式:类名: :new

范例:student: :new


练习:
集合里面存储姓名和年龄,比如:张三,23
要求:将数据封装成Student对象并收集到List集合中

public class FunctionDemo03 {
	public static void main(String[] args) {
		// 1.创建集合对象
		ArrayList list = new ArrayList<>();
		// 2.添加数据
		Collections.addAll(list, "张三,23", "李四,24", "王五,25", "赵六,26");

		// 3.封装成Student对象 并且收集到list集合中
		List newList = list.stream()
				.map(new Function() {
			@Override
			public Student apply(String s) {
				String[] arr = s.split(",");
				String name = arr[0];

				int age = Integer.parseInt(arr[1]);
				return new Student(name, age);
			}
		}).collect(Collectors.toList());
		System.out.println(newList);

		// 引用构造方法
		List newList2 = list.stream()
				.map(Student::new)
				.collect(Collectors.toList());
		System.out.println(newList2);
	}
}

//Student.java

public class Student {
	private String name;
	private int age;
	
	public Student() {}
	public Student(String str) {
		String[] arr = str.split(",");
		this. name = arr[0];
		
		this.age = Integer.parseInt(arr[1]);
	}
	public Student(String name,int age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

4. 其他调用方法

4.1  类名引用成员方法

格式:类名: :成员方法

范例:String: :subString

局限性:

  • 不能引用所有类中的成员方法。
  • 与抽象方法第一个参数有关,参数类型是什么那么就只能一怒用这个类中的方法。


练习:

集合里面一些字符串,要求变成大写后进行输出

public class FunctionDemo04 {
	public static void main(String[] args) {
		//抽象方法形参详解:
//		第一个参数: 表示被引用方法的调用者,决定了可以引用哪些类中的方法
//		           在Stream流中,第一个参数一般表示流里面的每一个数据
//		      假设流连的数据是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法
//		      
//		第二个参数到最后一个参数: 与被引用方法的形参保持一致
//		        如果没有第一个参数,说明被引用的方法需要时无参的成员方法 	
		
		// 1.创建集合对象
		ArrayList list = new ArrayList<>();
		// 2.添加数据
		Collections.addAll(list, "aaa", "bbb", "ccc", "ddd");
		
		//3.变成大写再输出
		//匿名内部类
		//String --> String
		list.stream().map(new Function() {
			@Override
			public String apply(String s) {
				return s.toUpperCase();	
			}
		}).forEach(s -> System.out.println(s));
		
		//类名引用
		list.stream()
		.map(String::toUpperCase)
		.forEach(s -> System.out.println(s)); 
	}
}

4.2  引用数组的构造方法

格式:数据类型[ ] : :new

范例:int[ ] : : new


练习:

集合中存储一些数据,收集到数组当中

public class FunctionDemo05 {
	public static void main(String[] args) {
		//细节:数组类型需要和数据类型保持一致
		
		// 1.创建集合并添加数据
		ArrayList list = new ArrayList<>();
		Collections.addAll(list, 1, 2, 3, 4, 5);
		
		//2.创建数组 数据收集到数组中
		//匿名内部类
		Integer[] arr = list.stream().toArray(new IntFunction() {
			@Override
			public Integer[] apply(int value) {
				return new Integer[value];
			}
		});
		System.out.println(Arrays.toString(arr));
		
		//方法引用
		Integer[] arr2 = list.stream().toArray(Integer[]::new);
		System.out.println(Arrays.toString(arr2));
	}
}

三、 方法引用综合小练习

1. 转为自定义对象并且收集到数组

需求:

集合中存储一些字符串的数据,比如:张三,23。

收集到Student类型的数组当中(使用方法引用完成)

public class FunctionText {
	public static void main(String[] args) {
		// 1.创建集合对象
		ArrayList list = new ArrayList<>();
		// 2.添加数据
		Collections.addAll(list, "张三,23", "李四,24", "王五,25", "赵六,26");
		
		
		//3.收集到Student类型的数组中
		//先把字符变成Student对象  再把Student对象收集起来
		
		//此时流中数据是Student还是String类型呢?  -> Student类型
		Student[] arr =list.stream()
				//先把字符变成Student对象
				.map(Student::new)
				//数组构造方法 -》构建数组并将数据存放进去
				.toArray(Student[]::new);
		
		System.out.println(Arrays.toString(arr));
	}
}

2. 获取部分属性并收集到数组

需求:

创建集合添加学生对象,学生对象属性:name,age

只获取姓名并放到数组当中(使用方法引用完成)

public class FunctionText {
	public static void main(String[] args) {
		//方法引用小技巧:
		//1.现在有没有一个方法符合当前需求
		//2.如果有,则看这个方法是否满足引用的规则
		//静态: 类名::方法名
		//成员方法:本类中:类名::方法名 this 
		//         其他类中: 对象名::方法名 super
		//构造方法:类名:: new
		
		// 1.创建集合
		ArrayList list = new ArrayList<>();
		// 2.添加元素
		list.add(new Student("张三", 23));
		list.add(new Student("李四", 24));
		list.add(new Student("王五", 25));

		// 3.获取姓名添加进数组
		// 匿名内部类
		String[] arr = list.stream().map(new Function() {
			@Override
			public String apply(Student student) {
				return student.getName();
			}
		}).toArray(String[]::new);
		System.out.println(Arrays.toString(arr));
		
		//方法引用
		String[] arr2 = list.stream().map(Student::getName).toArray(String[]::new);
		System.out.println(Arrays.toString(arr2));
	}
}

你可能感兴趣的:(JAVA基础进阶,java)