初识Lambda表达式

版权声明:版权所有,转载请注明出处 https://blog.csdn.net/yingshuanglu2564/article/details/82528968

一、简介

Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。

虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。

知识点:什么是语法糖?
语法糖(Syntactic sugar),是由Peter J. Landin(和图灵一样的天才人物,是他最先发现了Lambda演算,由此而创立了函数式编程)创造的一个词语,它意指那些没有给计算机语言添加新功能,而只是对人类来说更“甜蜜”的语法。
语法糖往往给程序员提供了更实用的编码方式,有益于更好的编码风格,更易读。不过其并没有给语言添加什么新东西。
需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换;
而且可以提高开发编码的效率,在性能上也不会带来损失

Lambda表达式还增强了集合库。 Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。 总的来说,lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。

 Lambda表达式基本语法

(parameters)-> expression 或 (parameters)-> {statements}

举例如下:

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)

二、操作

1、使用lambda表达式进行集合遍历

//使用lambda表达式遍历
public static void traverse() {
String[] atp = {"Rafael Nadal", "Novak Djokovic",  
			"Stanislas Wawrinka",  
			 "David Ferrer","Roger Federer",  
			 "Andy Murray","Tomas Berdych",  
			 "Juan Martin Del Potro"};  
	List<String> players =  Arrays.asList(atp);
		
	players.forEach((player) -> System.out.println(player+"; "));
}

2、lambda表达式操作对象

Person类(属性:firstName, lastName, job,  gender, age, salary)

数据准备:

public static List<Person> generateJavaProgrammer() {
    List<Person> javaProgrammers = new ArrayList<Person>() {  
    {  
	add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000));  
	add(new Person("Tamsen", "Brittany", "Java programmer", "female", 23,1500));  
	add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));  
	add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));  
	add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));  
	add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));  
	add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));  
	add(new Person("Jayden", "Corrina", "Java programmer", "female", 35,1700));  
	add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));  
	add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));  
	}  
    };
    return javaProgrammers;
}

public static List<Person> generatePhpProgrammer() {
    List<Person> phpProgrammers = new ArrayList<Person>() {  
    {  
	add(new Person("Jarrod", "Pace", "PHP programmer", "male", 34, 1550));  
        add(new Person("Clarette", "Cicely", "PHP programmer", "female", 23, 1200));  
	add(new Person("Victor", "Channing", "PHP programmer", "male", 32, 1600));  
	add(new Person("Tori", "Sheryl", "PHP programmer", "female", 21, 1000));  
	add(new Person("Osborne", "Shad", "PHP programmer", "male", 32, 1100));  
	add(new Person("Rosalind", "Layla", "PHP programmer", "female", 25, 1300));  
	add(new Person("Fraser", "Hewie", "PHP programmer", "male", 36, 1100));  
	add(new Person("Quinn", "Tamara", "PHP programmer", "female", 21, 1000));  
	add(new Person("Alvin", "Lance", "PHP programmer", "male", 38, 1600));  
	add(new Person("Evonne", "Shari", "PHP programmer", "female", 40, 1800));  
    }  
    };
    return phpProgrammers;
}

①forEach方法迭代输出所有程序员姓名

private static void traverseAllProgrammersName(List<Person> javaProgrammers, List<Person> phpProgrammers) {
	System.out.println("forEach方法迭代输出所有程序员姓名:");
	javaProgrammers.forEach((p) -> System.out.printf("%s %s;",p.getFirstName(),p.getLastName()));
		
	phpProgrammers.forEach((p)-> System.out.printf("%s %s;", p.getFirstName(),p.getLastName()));
}

②forEach方法給Java程序員工资涨10%

private static void raiseMoney(List<Person> javaProgrammers) {
	Consumer<Person> giveRaise = e -> e.setSalary(e.getSalary() / 100 * 10 +e.getSalary());
	javaProgrammers.forEach(e -> System.out.printf("%d",e.getSalary()));
	System.out.print("\n涨工资\n\t未加工资:\t");
		
	javaProgrammers.forEach(e -> System.out.printf("%s %s:¥%d;",e.getFirstName(),e.getLastName(),e.getSalary()));
	//涨工资
	javaProgrammers.forEach(giveRaise);
		
	System.out.print("\n\t输出加完工资后结果:\n\t");
		
	javaProgrammers.forEach(e -> System.out.printf("%s %s:¥%d;",e.getFirstName(),e.getLastName(),e.getSalary()));
}

③lambda表达式结合stream之filter的使用:筛选月薪超过1500元的PHP程序员

什么是Stream?

Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。

private static void filterPhpProgrammer(List<Person> phpProgrammers) {
	System.out.print("\n月薪超过1500元的PHP程序员:\n\t");
	phpProgrammers.stream()
                    .filter(p -> p.getSalary() > 1400)
                    .forEach(p -> System.out.printf("%s %s:¥%d;",p.getFirstName(),
                                                           p.getLastName(),p.getSalary()));
}

 

④自定义过滤器:筛选年龄大于25岁且月薪在¥1500以上的php程序员

private static void selfDefineFilter(List<Person> phpProgrammers) {
	System.out.print("\n自定义过滤器筛选php程序员:\n\t");
	//自定义过滤器
	Predicate<Person> ageFilter = p -> p.getAge() > 25;
	Predicate<Person> salaryFilter = p -> p.getSalary() > 1500;
	Predicate<Person> genderFilter = p -> "female".equals(p.getGender());
	
	System.out.print("年龄大于25岁且月薪在¥1500以上的女php程序员:\n\t");
	
	phpProgrammers.stream().filter(ageFilter)
			    .filter(genderFilter)
			    .filter(salaryFilter)
			    .forEach(p -> System.out.printf("%s %s:¥%d;",p.getFirstName(),
								p.getLastName(),p.getSalary()));
	//自定义过滤器的好处就是可以重用
}

⑤limit方法的使用:筛选前4个php程序员

private static void limitPhpProgrammer(List<Person> phpProgrammers) {
	System.out.println("\n筛选前4个php程序员:");
	phpProgrammers.stream()
		    .limit(4)
		    .forEach(p -> System.out.printf("%s %s;",p.getFirstName(),
						p.getLastName()));
	//可以配合filter进行进一步筛选
}

⑥coloect方法的使用:先根据name排序再根据salary排序

private static void streamSortJavaProgrammer(List<Person> javaProgrammers) {
	System.out.print("\nstream排序:\n\t根据name排序并只显示前5个javaProgrammer:\n\t");
	
	List<Person> sortedJavaProgrammers = javaProgrammers.stream()
						.sorted((p1,p2) -> p1.getFirstName().compareTo(p2.getFirstName()))
						.limit(5)
						.collect(Collectors.toList());
	//输出结果
	sortedJavaProgrammers.forEach(p -> System.out.printf("%s %s;",p.getFirstName(),
						p.getLastName()));
	
	System.out.print("\n\t再根据 salary 排序 javaProgrammer:\n\t");
	sortedJavaProgrammers = sortedJavaProgrammers.stream()
						.sorted((p1,p2) -> p2.getSalary() - p1.getSalary())
						.collect(Collectors.toList());
	sortedJavaProgrammers.forEach(p -> System.out.printf("%s %s:¥%d;",p.getFirstName(),
			                                        p.getLastName(),p.getSalary()));
}

⑦max、min的用法:获得Java程序员中工资最高和最低者的信息

private static void getExtreValue(List<Person> javaProgrammers) {
	System.out.print("\n获得最值:\n\t工资最低的javaProgrammer:\n\t");
	Person minSalaryPm = javaProgrammers.stream().min((p1,p2) -> p1.getSalary() - p2.getSalary()).get();

	System.out.print(minSalaryPm.getFirstName()+" "+minSalaryPm.getLastName()+":¥"+minSalaryPm.getSalary());
	
	System.out.print("\n\t工资最高的javaProgrammer:\n\t");
	
	Person maxSalaryPm = javaProgrammers.stream().max((p1,p2) -> p1.getSalary() - p2.getSalary()).get();
	
	System.out.println(maxSalaryPm.getFirstName()+" "+maxSalaryPm.getLastName()+":¥"+maxSalaryPm.getSalary());
}

注:此处工资与元数据多了10%是因为前raiseSalary操作所致。

三、总结

通过学习初步掌握了lambda表达式的使用,lambda表达式让我们可以用更少的代码来实现相同的功能,因此lambda表达式可以使代码变得更加简洁紧凑,便捷的写法提高了开发编码的效率。

四、参考 

http://www.runoob.com/java/java8-lambda-expressions.html

https://www.cnblogs.com/franson-2016/p/5593080.html

五、示例代码

链接:https://pan.baidu.com/s/1hBGFIxS5yf2CPnjZsunGMA 密码:r0fq

猜你喜欢

转载自blog.csdn.net/yingshuanglu2564/article/details/82528968