首页 > 编程语言 >JAVA进阶 —— 方法引用

JAVA进阶 —— 方法引用

时间:2023-11-24 17:36:10浏览次数:40  
标签:JAVA String list 引用 new 方法 public 进阶

原文链接:https://blog.csdn.net/hdakj22/article/details/129453599

一、 内容概述

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

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

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

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

二、方法引用的分类

1. 引用静态方法

格式: 类名:: 静态方法
范例: Integer:: parseInt

public class FunctionTest {
	public static void main(String[] args) {
		//1.创建集合并添加对象
		ArrayList<String> list = new ArrayList<>();
		Collections.addAll(list, "1","2","3","4","5");
		
		//2.转变成int类型
		list.stream().map(new Function<String, Integer>() {
			@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<String> 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<String>() {
			@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<String> list = new ArrayList<>();
		// 2.添加数据
		Collections.addAll(list, "张三,23", "李四,24", "王五,25", "赵六,26");
 
		// 3.封装成Student对象 并且收集到list集合中
		List<Student> newList = list.stream()
				.map(new Function<String, Student>() {
			@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<Student> 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<String> list = new ArrayList<>();
		// 2.添加数据
		Collections.addAll(list, "aaa", "bbb", "ccc", "ddd");
		
		//3.变成大写再输出
		//匿名内部类
		//String --> String
		list.stream().map(new Function<String, String>() {
			@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<Integer> list = new ArrayList<>();
		Collections.addAll(list, 1, 2, 3, 4, 5);
		
		//2.创建数组 数据收集到数组中
		//匿名内部类
		Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
			@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<String> 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<Student> 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<Student, String>() {
			@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,String,list,引用,new,方法,public,进阶
From: https://www.cnblogs.com/zoufh/p/17854259.html

相关文章

  • JavaScript数组中的常用函数解析
    1.splice方法当使用splice()方法时,可以传递不同的参数来实现不同的操作。以下是splice()方法的参数说明:array.splice(start,deleteCount,item1,item2,...);start:必需,指定要进行操作的起始索引位置。如果该值为负数,则表示从数组末尾开始计算的偏移量。例如,-1表示倒数第......
  • java 关于 Finalizer 过多导致内存(Res)缓慢上涨
     病因:事情的起因是由Flume的项目采集问题引发的.测试人员发现用top命令查看采集进程的Res一直不断上涨姿势.所以怀疑是内存泄漏.  一,对症下药首先,第一步肯定是先瞅瞅代码,看看有没有那些资源啥的没关闭,正如读者所想----没有发现.二,通过辅助工具最......
  • 这篇保证你彻底搞懂Java NIO的Selector事件选择器
     Selector提供选择执行已经就绪的任务的能力,使得多元I/O成为可能,就绪选择和多元执行使得单线程能够有效率地同时管理多个I/Ochannel。C/C++许多年前就已经有select()和poll()这两个POSIX(可移植性操作系统接口)系统调用可供使用。许多os也提供相似的功能,但对Java程序......
  • Java实验报告五
    实验五实验名称:文件与I/O流实验目的:掌握文件与输入输出流的使用。实验时间:(2学时)实验类型:验证型实验内容:1.创建类:FindFile.java,遍历当前目录,打印目录中文件名称,目录打印”isDirectory”,文件打印“isfile”。修改程序打印当前目录及子目录信息。提示:当前目录名用......
  • JavaWeb中的文件的上传和下载
    文件上传1.要有一个form标签,method=post请求2.form标签的encType属性的值必须为multipart/form-data值3.在from标签中使用inputtype=file添加上传的文件4.编写服务器代码接收上传的数据Content-Type:表示提交的数据类型enctype="multipart/form-data":表示提交的数据,以多段(每......
  • Java线程生命周期
    操作系统线程生命周期操作系统线程生命状态有5种。初始状态(New)进程正在被创建时的状态。仅为线程对象开辟了一块堆内存,实际上线程在操作系统层面还未创建。就绪状态(Ready)可运行,由于其他进程处于运行状态而暂时停止运行运行状态(Running)该进程此时正占用CPU......
  • Java实验报告
    实验一实验名称:JAVA中循环结构实验目的:熟悉循环结构,熟悉JAVA类的定义以及参数的传递。实验时间:(2学时)实验类型:验证型实验内容:(1)金字塔:Pyramid.java在屏幕上显示一个由星型符号“*”组成的金字塔图案,要求用户设置金字塔的高度,程序能根据用户设置的高度打印金字塔,......
  • Java系列之 String indexOf() 方法
    我|在这里 ......
  • 03_Exception in thread “main“ java.lang.AssertionError
    问题maven构建报错***[INFO]---maven-compiler-plugin:3.8.1:compile(default-compile)@engine_auth---[INFO]Changesdetected-recompilingthemodule![INFO]Compiling38sourcefilestoC:\Users\...\target\classes[INFO]-----------------------------......
  • [Java] 解析Xml配置文件
    1、解析方法importjavax.xml.parsers.DocumentBuilder;importjavax.xml.parsers.DocumentBuilderFactory;importorg.w3c.dom.Document;importorg.w3c.dom.NamedNodeMap;importorg.w3c.dom.Node;importorg.w3c.dom.NodeList;publicstaticMap<String,String>pars......