文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

简单易懂的java8新特性之lambda表达式知识总结

2024-04-02 19:55

关注

一、概念

从本质上来说,它就是一个匿名函数,可以用来直接实现接口中的方法,从而简化代码。但是Lambda有一个限制,不能实现接口中的所有方法,所以Lambda表达式只能用于有且仅有一个必须需要实现的方法接口,这里需要注意必须需要实现这六个字。


public interface Printer {
//有一个需要实现的方法,可以使用Lambda表达式
	void print();
}

public interface Printer {
//有一个需要实现的方法,可以使用Lambda表达式
	void print();
	//这里虽然有一个方法,但接口提供了默认实现,因此不是必须要实现的
	default void printDetail(){}
}

public interface Printer {
//有一个需要实现的方法,可以使用Lambda表达式
	void print();
//这里虽然有一个需要实现的方法,但不是必须要实现的,因为toString()是Object类中的.
String toString();	
}

public interface Printer {
//有一个需要实现的方法,可以使用Lambda表达式
	void print();
//这里虽然有一个需要实现的方法,但不是必须要实现的,因为toString()是Object类中的.
String toString();	
}

像这种只有一个必须要实现的方法的接口,在java8中称之为函数式接口,在定义接口时可以在接口名上方加上@FunctionInterface标签,用于验证此接口是否为函数式接口。如果这个接口定义好之后不是函数式接口,那么接口名处会报错。
在使用Lambda表达式的时候,不需要关注方法名,只需要关注方法参数和返回值即可。基本语法很简单:


(参数列表)->{
	方法体
};

二、用法比较

java中实现接口的方式在java8之前有两种:定义接口的实现类,使用匿名类,但Lambda表达式相比于这种方法都简单很多。以上文的Printer接口为例,实现如下:

2.1 实现类


class PrinterImpl implements Printer{

	@Override
	public void print() {
		System.out.println("Hello World");
	}
	
}

2.2 匿名类


class PrinterAnonymous {

	Printer printer = new Printer() {
		
		@Override
		public void print() {
			System.out.println("Hello World");
			
		}
	};
	
}

2.3 Lambda


class PrinterLambda{
	Printer p = ()-> System.out.println("Hello World");
}

比较上文三种实现方式,很显示Lambda的实现比前两种简单很多。

三、基本用法

3.1 无参数无返回值接口方法


@FunctionalInterface
public interface Printer {
	void print();
}
public class Tester {
	public static void main(String[] args) {
		// 方法一,无返回值的情况,方法体只有一条语句,可以省略大括号
		Printer p1 = () -> System.out.println("Hello World 1");
		p1.print();
		// 方法二,标准定义
		Printer p2 = () -> {
			System.out.println("Hello World 2");
		};
		p2.print();
	}
}

3.2 一个参数无返回值接口方法


@FunctionalInterface
public interface Printer {
	void print(String str);
}

public class Tester {

	public static void main(String[] args) {
		// 方法一,无返回值的情况,方法体只有一条语句,可以省略大括号
		//因为这里只有一个参数,小括号也可以省略,小括号省略的前提是:有且仅有一个参数
		//Printer p1 = s -> System.out.println(s);
		Printer p1 = (s) -> System.out.println(s);
		p1.print("Hello World 1");
		// 方法二,无返回值的情况,方法体只有一条语句,可以省略大括号
		Printer p2 = (String s) -> System.out.println(s);
		p2.print("Hello World 2");
		// 方法三,标准定义
		Printer p3 = (String s) -> {
			System.out.println(s);
		};
		p3.print("Hello World 3");
	}
}

3.3 多个参数无返回值接口方法


@FunctionalInterface
public interface Printer {
	void print(String str1,String str2);
}

public class Tester {

	public static void main(String[] args) {
		// 方法一,无返回值的情况,方法体只有一条语句,可以省略大括号
		//参
		Printer p1 = (s1,s2) -> System.out.println(s1+" "+s2);
		p1.print("Hello World 1","Java 1");
		// 方法二,无返回值的情况,方法体只有一条语句,可以省略大括号
		Printer p2 = (String s1,String s2) -> System.out.println(s1+" "+s2);
		p2.print("Hello World 2","Java 2");
		// 方法三,标准定义
		Printer p3 = (String s1,String s2) -> {
			System.out.println(s1+" "+s2);
		};
		p3.print("Hello World 3","Java 3");

	}

}

3.4 无参数有返回值接口方法


@FunctionalInterface
public interface Printer {
	boolean print();
}


public class Tester {

	public static void main(String[] args) {
		// 方法一,有返回值的情况,只有一条语句,return关键字的有无决定能否活力大括号
		Printer p1 = () ->  true;
		boolean has1 = p1.print();
		System.out.println(has1);//测试返回结果
		// 方法二,标准定义
		Printer p2 = () -> {return true;};
		boolean has2 = p2.print();
		System.out.println(has2);//测试返回结果
		
	}
}

3.5 一个参数有返回值接口方法


@FunctionalInterface
public interface Printer {
	boolean print(boolean good);
}
public class Tester {

	public static void main(String[] args) {
		// 方法一,有返回值的情况,只有一条语句,return关键字的有无决定能否活力大括号
	   //因为这里只有一个参数,小括号也可以省略,小括号省略的前提是:有且仅有一个参数
	   //Printer p1 = good ->  good;
		Printer p1 = (good) ->  good;
		boolean has1 = p1.print(true);
		System.out.println(has1);
		// 方法二,标准定义
		Printer p2 = (good) -> {return good;};
		boolean has2 = p2.print(false);
		System.out.println(has2);
		
	}
}

3.6 多个参数有返回值接口方法


@FunctionalInterface
public interface Printer {
	boolean print(boolean good1,boolean good2);
}

public class Tester {

	public static void main(String[] args) {
		// 方法一,有返回值的情况,只有一条语句,return关键字的有无决定能否活力大括号
		Printer p1 = (good1,good2) ->  good1;
		boolean has1 = p1.print(true,false);
		System.out.println(has1);
		// 方法二,标准定义
		Printer p2 = (good1,good2) -> {return good1;};
		boolean has2 = p2.print(false,false);
		System.out.println(has2);
		
	}
}

四、函数引用

在实现一个接口的方法时,如果现有的其他地方的某个函数已经实现了接口方法的逻辑,可以使用方法引用直接将这个逻辑引用过来。

4.1 静态方法引用

语法:


接口名 变量名 = 类 ::已实现的方法

注意事项:

示例:
Printer 需要实现的方法在Checker中有同样的实现,这样就可以直接引用过来


@FunctionalInterface
public interface Printer {
	String print(boolean good1,boolean good2);
}

public class Checker {
	public static String check(boolean a,boolean b) {
		if(a && b) {
			return "Java is good";
		}else if (!a && b) {
			return "Java is better";
		}
		return "Java is best";
	}
}
public class Tester {

	public static void main(String[] args) {
		Printer p1 = Checker::check;//用类名来引用
		System.out.println(p1.print(true, true));
		
	}
}

4.2 非静态方法引用

语法:


接口名 变量名 = 对象 ::静态方法

注意事项:

示例:
Printer 需要实现的方法在Checker中有同样的实现,这样就可以直接引用过来


@FunctionalInterface
public interface Printer {
	String print(boolean good1,boolean good2);
}

public class Checker {
	public String check(boolean a,boolean b) {
		if(a && b) {
			return "Java is good";
		}else if (!a && b) {
			return "Java is better";
		}
		return "Java is best";
	}
}
public class Tester {

	public static void main(String[] args) {
		Printer p1 = new Checker()::check;//必须用对象来引用
		System.out.println(p1.print(true, true));
		
	}
}

4.3 构造方法的引用

如果一个函数式接口中定义的方法仅仅是为了得到一个对象,此时我们就可以使用构造方法的引用,简化这个方法的实现
语法:


接口名 变量名 = 类名 ::new

注意事项:
可以通过接口中的方法参数,区分引用不同的构造方法
示例:


@FunctionalInterface
public interface Printer1 {
	Checker getCheck();
}

@FunctionalInterface
public interface Printer2 {
	Checker getCheck(int a);
}

public class Checker {
	int times;
	public Checker() {
		System.out.println("I am none parameter");
	}
	
	public Checker(int a) {
		System.out.println("I have one parameter");
	}
}

public class Tester {

	public static void main(String[] args) {
		//引用无参构造方法
		Printer1 p1 = Checker::new;
		p1.getCheck();
		//引用有参构造方法
		Printer2 p2 = Checker::new;
		p2.getCheck(1);
		
	}
}

4.4 对象方法的特殊引用

如果实现某些接口的时候,Lambda表达式中包含了某一个对象,此时方法体中,直接使用这个对象调用它的某一个方法就可以完成整个的逻辑。其他的参数,可以作为调用方法的参数。此时,可以对这种实现进行简化。
示例:


@FunctionalInterface
public interface Printer1 {
	int getCheck(Checker checker);
}

@FunctionalInterface
public interface Printer2 {
	void setCheck(Checker checker, int a);
}

public class Tester {

	public static void main(String[] args) {
		Checker checker = new Checker();
		checker.setTimes(100);
		// 没有简化前,按照之前的方法使用lambda表达式
		Printer1 p1 = x -> x.getTimes();
		System.out.println(p1.getCheck(checker));//测试

		// 简化之后
		Printer1 p11 = Checker::getTimes;
		System.out.println(p11.getCheck(checker));//测试
		
		// 没有简化前,按照之前的方法使用lambda表达式
		Printer2 p2 = (x,y)-> x.setTimes(y);
		p2.setCheck(checker, 50);
		System.out.println(checker.getTimes());//测试
		// 简化之后
		Printer2 p22 = Checker::setTimes;
		p22.setCheck(checker, 30);
		System.out.println(checker.getTimes());//测试

	}
}

五、注意

当在Lambda表达式中使用了某一个局部变量,那么这个局部变量的值在Lambda表达式之外,不可以被改变,因为默认将其定义成final常量。但全局变量变量没有这方面的限制。
示例:


@FunctionalInterface
public interface Printer {
	void setTime();
}
public class Tester {

	public static void main(String[] args) {
		int time = 10;
		Printer p = () -> System.out.println(time);//这里出错了,因为下一行对time进行修改
		time = 15;//这里的值不能改变,会导致上一行出错

	}
}

基本概括了Lambda表达式的所有用法,不足之处,请谅解,谢谢!

到此这篇关于简单易懂的java8新特性之lambda表达式知识总结的文章就介绍到这了,更多相关java lambda表达式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯