JDK1.8新特性(部分)【Lambda表达式、函数式接口】--学习JavaEE的day41

这篇具有很好参考价值的文章主要介绍了JDK1.8新特性(部分)【Lambda表达式、函数式接口】--学习JavaEE的day41。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

day41

JDK1.8新特性

JDK1.8新特性简介

  • 速度更快 - 优化底层源码,比如HashMap、ConcurrentHashMap
  • 代码更少 - 添加新的语法Lambda表达式
  • 强大的Stream API
  • 便于并行
  • 最大化减少空指针异常 - Optional

Lambda表达式

简介

Lambda是一个匿名函数(方法), 允许把函数作为一个方法的参数 。利用Lambda表达式可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。

一般都是优化匿名内部类

基础语法

无参数、无返回值的抽象方法

public class Test1 {
	@Test
	public void test01() {
//		I1 i1 = new I1() {
//			@Override
//			public void method() {
//				System.out.println("传统使用匿名内部类的方式");
//			}
//		};
//		i1.method();

//		I1 i1 = ()->{
//			System.out.println("使用lambda表达式的方式");
//		};
//		i1.method();
        
        //lambda表达式里面只有一个语句情况,大括号可以省略进行简化代码
		I1 i1 = ()-> System.out.println("采用Lambda表达式的方式");
		i1.method();
	}
}
interface I1{
	public void method();//无参数、无返回值的抽象方法
}

一个参数、无返回值的抽象方法

外部new匿名内部类调用方法时,参数看接口定义的规范里的参数类型

public class Test01 {
	public static void main(String[] args) {
		
//		I1 i1 = new I1() {
//			@Override
//			public void method(String str) {
//				System.out.println("使用传统匿名内部类的方式:" + str);
//			}
//		};
//		i1.method("过往云烟");
		
//		I1 i1 = (String str)->{
//			System.out.println("使用lambda表达式的方式:" + str);
//		};
//		i1.method("过往云烟");
		
//		I1 i1 = (String str)->System.out.println("使用lambda表达式的方式:" + str);
//		i1.method("过往云烟");
		
		
//		I1 i1 = (str)->System.out.println("使用lambda表达式的方式:" + str);
//		i1.method("过往云烟");
		
		I1 i1 = str->System.out.println("使用lambda表达式的方式:" + str);
		i1.method("过往云烟");
	}
}
public interface I1 {

	public void method(String str);//一个参数、无返回值的抽象方法
}

多个参数、无返回值的抽象方法

public class Test01 {
	public static void main(String[] args) {
		
//		I1 i1 = new I1() {
//			@Override
//			public void method(String str, int i) {
//				System.out.println("使用传统匿名内部类的方式:" + str + " -- " + i);
//			}
//		};
//		i1.method("过往云烟", 666);
		
//		I1 i1 = (String str,int i)->{
//			System.out.println("使用lambda表达式的方式:" + str + " -- " + i);
//		};
//		i1.method("过往云烟", 777);
		
//		I1 i1 = (String str,int i)->System.out.println("使用lambda表达式的方式:" + str + " -- " + i);
//		i1.method("过往云烟", 888);
		
		I1 i1 = (str, i)->System.out.println("使用lambda表达式的方式:" + str + " -- " + i);
		i1.method("过往云烟", 999);
		
	}
}
public interface I1 {
    //多个参数、无返回值的抽象方法
	public void method(String str,int i);
}

多个参数、有返回值的抽象方法

public class Test01 {
	public static void main(String[] args) {
	
//		I1 i1 = new I1() {
//			@Override
//			public String method(int a, int b) {
//				return "使用传统匿名内部类的方式:" + (a+b);
//			}
//		};
//		String method = i1.method(10, 10);
//		System.out.println(method);
		
//		I1 i1 = (int a,int b)->{
//			return "使用lambda表达式的方式:" + (a+b);
//		};
//		String method = i1.method(20, 20);
//		System.out.println(method);
		
		I1 i1 = (a, b)-> "使用lambda表达式的方式:" + (a+b);
		String method = i1.method(30, 30);
		System.out.println(method);
		
	}
}
public interface I1 {
	//多个参数、有返回值的抽象方法
	public String method(int a,int b);
}
注意点
  1. 重写方法的形参只有一个时,可以不加小括号
  2. Lambda表达式当中不允许声明一个与局部变量同名的参数或者局部变量
  3. Lambda表达式中访问外层的局部变量,外层的局部变量自动变成隐式常量,默认添加final
  4. 重写方法的形参同时加类型或同时不加类型
public class Test1 {
	@Test
	public void test01() {
		int x;
		int num = 10;
		I1 i1 = x -> System.out.println(x + (num++));
        i1.method(1000);
		
		I2 i2 = (int x,int y) -> {
			int result = x+y;
			return result;
		};
		int result = i2.method(10, 20);
		System.out.println(result);
	}
}
interface I1{
	public void method(int num1);
}
interface I2{
	public int method(int num1,int num2);
}
案例
案例1

1.调用Collections.sort()方法,通过定制排序比较两个Student对象(先按年龄比较,年龄相同按照薪资比较),使用Lambda表达式作为参数传递

注意:比较时注意不能用减,因为doublue减后的小数会在转int损失精度,ps:0.2变为0

public class Test01 {

	public static void main(String[] args) {
		
		List<Student> stuList = Arrays.asList(
				new Student("张三", 28, 4800,Course.JAVA),
				new Student("李四", 36, 7200,Course.JAVA),
				new Student("王五", 19, 9600,Course.HTML),
				new Student("赵六", 42, 6100,Course.HTML),
				new Student("孙七", 23, 9600,Course.PYTHON),
				new Student("吴八", 28, 3000,Course.PYTHON));
		
//		Collections.sort(stuList, new Comparator<Student>() {
//			@Override
//			public int compare(Student o1, Student o2) {
//				if(o1.equals(o2)){
//					return 0;
//				}
//				
//				int compare = Integer.compare(o1.getAge(), o2.getAge());
//				if(compare != 0){
//					return compare;
//				}
//				
//				return Double.compare(o1.getSalary(), o2.getSalary());
//			}
//		});
		
		Collections.sort(stuList, (o1,o2)->{
			if(o1.equals(o2)){
				return 0;
			}
			
			int compare = Integer.compare(o1.getAge(), o2.getAge());
			if(compare != 0){
				return compare;
			}
			
			return Double.compare(o1.getSalary(), o2.getSalary());
		});
		
		for (Student stu : stuList) {
			System.out.println(stu);
		}
		
	}
}
public enum Course{//课程枚举
	JAVA,HTML,PYTHON;
}
public class Student{//学生类
	
	private String name;
	private int age;
	private double salary;
	private Course course;
    //有参、无参、get、set方法【略】
@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((course == null) ? 0 : course.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		long temp;
		temp = Double.doubleToLongBits(salary);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (course != other.course)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))
			return false;
		return true;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("Student [name=");
		builder.append(name);
		builder.append(", age=");
		builder.append(age);
		builder.append(", salary=");
		builder.append(salary);
		builder.append(", course=");
		builder.append(course);
		builder.append("]");
		return builder.toString();
	}

}
案例2

2.创建I1接口,创建抽象方法:public String getValue(String str),在测试类中编写方法使用接口作为参数,将一个字符串转为大写,并作为方法的返回值

public class Test01 {
    
	public static void main(String[] args) {
		
		String str = method("abc", (x)-> {
			return x.toUpperCase();
		});
		System.out.println(str);
		
		
	}
	
	public static String method(String str,I1 i1){
		return i1.getValue(str);
	}
}

interface I1{
	public String getValue(String str);
}
案例3

3.创建I1<T,R>接口,泛型T为参数,R为返回值,创建抽象方法:public R add(T t1,T t2),在测试类中编写方法使用接口作为参数,计算两个long类型的和

public class Test01 {

	public static void main(String[] args) {
		
		long addLong = addLong(100,200,(a,b)->{
			return a+b;
		});
		System.out.println(addLong);
		
		
	}
	
	public static long addLong(long l1,long l2,I1<Long,Long> i1){
		return i1.add(l1, l2);
	}
}
interface I1<T,R>{
	public R add(T t1,T t2);
}

函数式接口

简介

函数式接口是指仅仅只包含一个抽象方法的接口,jdk1.8提供了一个@FunctionalInterface注解来定义函数式接口,如果我们定义的接口不符合函数式的规范便会报错。配合Lambda表达式一起使用

四大核心函数式接口
函数式接口 参数类型 返回类型 用途
Consumer 消费型接口 T void void accept(T t);
Supplier 供给型接口 void T T get();
Function<T, R> 函数型接口 T R R apply(T t);
Predicate 断言型接口 T boolean booelan test(T t);
BiConsumer<T, U> T,U void 对类型为T,U参数应用操作。包含方法为void accept(T t,U u);
BiFunction<T, U, R> T,U R 对类型为T,U参数应用操作,并返回R类型的结果。包含方法为R apply(T t,U u);
UnaryOperator extends Function<T, T> T T 对类型为T的对象进行一元运算,并返回T类型的结果。包含方法为T apply(T t);
BinaryOperator extends BiFunction<T,T,T> T,T T 对类型为T的对象进行二元运算,并返回T类型的结果。包含方法为T apply(T t1,T t2);
ToIntFunction ToLongFunction ToDoubleFunction T int long double 分别计算int、long、double值的函数
IntFunction LongFunction DoubleFunction int long double R 参数为int、long、double类型的函数

应用场景:当项目中需要一个接口,并且该接口中只有一个抽象方法,就没必要去创建新的接口,直接选择Java提供的使用合适的函数式接口即可

案例替换

对Lambda表达式案例,使用合适的函数式接口去替换I1

创建I1接口,创建抽象方法:public String getValue(String str),

在测试类中编写方法使用接口作为参数,将一个字符串转为大写,并作为方法的返回值

注意:使用合适的函数式接口去替换I1

函数和方法:前端习惯称函数,后端习惯称方法,简单理解一个意思但非区别

函数式接口,一个抽象方法,超过就会报错
函数式接口替换接口,就案例来看更改方法里的接口,用函数调用方法,少一层

public class Test01 {

	public static void main(String[] args) {
		
		String str = method("abc", (x)->{
			return x.toUpperCase();
		});
		System.out.println(str);
		
		
	}
	
	public static String method(String str,Function<String, String> fun){
		return fun.apply(str);
	}
}
public class Test02 {

	public static void main(String[] args) {
		
		String str = method("abc", (x)->{
			return x.toUpperCase();
		});
		System.out.println(str);
		
		
	}
	
	public static String method(String str,UnaryOperator<String> uo){
		return uo.apply(str);
	}
}

创建I1<T,R>接口,泛型T为参数,R为返回值,创建抽象方法:public R add(T t1,T t2),

在测试类中编写方法使用接口作为参数,计算两个long类型的和

public class Test01 {

	public static void main(String[] args) {
		
		long addLong = addLong(100,200,(a,b)->{
			return a+b;
		});
		System.out.println(addLong);
		
		
	}
	
	public static long addLong(long l1,long l2,BiFunction<Long, Long, Long> bf){
		return bf.apply(l1, l2);
	}
}
public class Test02 {
	public static void main(String[] args) {
		
		long addLong = addLong(100,200,(a,b)->{
			return a+b;
		});
		System.out.println(addLong);
		
		
	}
	
	public static long addLong(long l1,long l2,BinaryOperator<Long> bo){
		return bo.apply(l1, l2);
	}
}

总结

1.lambda表达式(其实就有优化匿名内部类的方案)
注意:使用lambda表达式必须有多态的思想

2.函数式接口
该接口中只有一个抽象方法
@FunctionInterface这个注解表示该接口是函数式接口

经验:
如果你想玩转lambda表达式,必须先去学习匿名内部类+多态
函数式接口应用场景:需求要你写个接口,这个接口只有一个抽象方法,就用函数式接口去代替文章来源地址https://www.toymoban.com/news/detail-857579.html

到了这里,关于JDK1.8新特性(部分)【Lambda表达式、函数式接口】--学习JavaEE的day41的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++11新特性lambda 表达式

    Lambda 表达式的基本语法是:[] (参数列表) - 返回值类型 {函数体}。 方括号([])表示捕获列表,用来指定在 lambda 表达式中可以访问的外部变量。 参数列表和返回值类型与普通函数的参数列表和返回值类型相同。 函数体则是实际的代码逻辑。 不接受任何参数:[] { 函数体 } 接受

    2024年02月14日
    浏览(28)
  • C11新特性之Lambda表达式

    优点:  1.可以定义简短的函数。 2.使用lambda表达式使代码更紧凑,可读性更好。 语法: [] 表示不捕获任何变量 [this] 表示值传递方式捕捉当前的 this 指针  [] 表示引用传递方式捕捉所有父作用域的变量(包括 this ) [var] 表示 引用传递 捕捉变量 var [=] 表示值传递方式捕获所

    2023年04月22日
    浏览(31)
  • Java8新特性—Lambda表达式

    Java 8是Java编程语言的一个版本,于2014年发布。它引入了许多新的特性和改进。 Lambda表达式是Java 8中引入的一个重要的新特性,它提供了一种更加简洁、灵活的方式来编写函数式接口的实现,从而提高了代码的可读性和简洁性。 在本文中,我们将介绍Lambda表达式的基本语法、

    2024年02月03日
    浏览(33)
  • Java8新特性-Lambda表达式

    Lambda表达式 Lambda是一个匿名函数, 可以把lambda表达式理解为是一段可以传递的代码,(将代码像数据一样传递) 变化 需求: 求 薪资高于5000的员工信息 Lambda基本语法 在 java8 中引入了一个新的操作符 \\\"-\\\" , 箭头操作符, 箭头操作符 将Lambda表达式拆分为两部分: 左侧: Lambda表达式的参

    2024年02月01日
    浏览(31)
  • Java 8 新特性之Lambda表达式

    函数式编程(Functional Programming)是把函数作为基本运算单元,函数可以作为变量,可以接收函数,还可以返回函数。历史上研究函数式编程的理论是Lambda演算,所以我们经常把支持函数式编程的编码风格称为Lambda表达式。 在Java中使用Lambda表达式的前提:需要是函数接口。

    2024年01月22日
    浏览(31)
  • Java 8 新特性——Lambda 表达式(2)

            Java Stream函数式编程接口最初在Java 8中引入,并且与 lambda 一起成为Java开发里程碑式的功能特性,它极大的方便了开放人员处理集合类数据的效率。         Java Stream就是一个数据流经的管道,并且在管道中对数据进行操作,然后流入下一个管道。有学过linux

    2024年02月11日
    浏览(29)
  • 探索Python中的函数式编程:Lambda表达式与函数式工具【第135篇—Lambda表达式】

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在Python编程世界中,函数式编程逐渐成为了一种流行的范式,特别是在处理数据和编写简洁、高效代码时。函数式编程的核心思想是将计算视

    2024年04月08日
    浏览(73)
  • 【C++干货铺】C++11新特性——lambda表达式 | 包装器

    ========================================================================= 个人主页点击直达:小白不是程序媛 C++系列专栏:C++干货铺 代码仓库:Gitee ========================================================================= 目录 C++98中的排序 lambda表达式 lambda表达式语法 表达式中的各部分说明 lambda表达式的使

    2024年01月21日
    浏览(34)
  • 【C++】STL 算法 ② ( foreach 循环中传入 函数对象 / Lambda 表达式处理元素 | foreach 循环算法 | Lambda 表达式 - 匿名 函数对象 / 仿函数 )

    在 C++ 语言中 , std::foreach 循环 虽然 不是标准库的一部分 , 但是 C ++ 编译器 提供了对 该语法 的支持作为扩展 ; 使用 该 std::foreach 循环 , 可以用于 遍历 STL 标准模板库 中提供的容器 , 如 vector 单端数组 , list 双向链表 , map 映射 , set 集合 等 容器 中的元素 ; std::for_each 是一个算

    2024年02月02日
    浏览(53)
  • C++的lambda表达式(匿名函数)

    从C++11开始,C++也支持使用lambda表达式(匿名函数)。Lambda表达式是一种便捷的方式,可以定义一个函数对象,而无需使用显式的函数对象类型或函数指针语法。 C++中的 lambda表达式的基本语法如下: 其中各个部分的含义如下: capture list :用于指定所捕获的外部变量列表。可

    2024年02月08日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包