Java8 Lamdba表达式 003

继续lamdba。上篇Java8 Lamdba表达式 002讲了使用lamdba对集合元素进行排序,本篇讲述使用lamdba对集合元素过滤,演示样例代码沿用上篇:

001

public class SortingPlayer {

	public static void main(String[] args) {
		List<Player> playerList = new ArrayList<>();
		playerList.add(new Player("Black", "White", 9));
		playerList.add(new Player("John", "Hello", 2));
		playerList.add(new Player("Machicel", "Jackson", 7));
		playerList.add(new Player("Ani", "Hessius", 4));
		playerList.add(new Player("Mark", "Towns", 3));
		playerList.add(new Player("Huge", "Nana", 6));
	}
}

class Player{
	//类定义參考上篇
}

如001所看到的 创建一个集合 并在集合中加入几条元素。名字。分数。如今要对集合中的元素进行过滤,比方我要获取全部分数大于等于5的元素把它们放到还有一个集合中,打印出符合条件的元素个数。

002

/**
 * Specifying Filter Criteria on a Collection of Data
 */
List<Player> bigGoals = new ArrayList<>();
playerList.stream().filter(
		p -> p.getGoals() >= 5)
		.forEach(element -> bigGoals.add(element));
System.out.println("Number of Players Matching Criteria: " + bigGoals.size());

002中新建一个集合用来保存符合条件的元素,使用stream因为它包括易用的过滤功能。依据playerList生成stream然后在上面调用过滤功能,过滤的处理使用了lamdba表达式。

lamdba表达式传递一个Player对象作为參数,然后依据条件goals>=5进行过滤。假设符合则往新建的集合加入这个元素。

通过以上的学习。我们应该对lamdba表达式有着深刻的印象了,它声明一个功能接口,也就是仅仅有一个抽象方法的接口,并用lamdba表达式实现。

或者使用Function<argument,return>定义。并实现。

在传统的Java类中。也有着仅仅有一个抽象方法的接口。比方新建一个线程java.util包下的Runnable接口,它里面仅仅有一个run抽象方法。如今我们考虑使用lamdba表达式实现Runnable接口。并跟传统的实现进行比較。

003

public class RunnableCompare {

	public static void main(String[] args) {
		Runnable oldRunnable = new Runnable() {
			@Override
			public void run() {
				int x = 5 * 3;
				System.out.println("The variable using the old way equals: " + x);
			}
		};
		Runnable lambdaRunnable = () -> {
			int x = 5 * 3;
			System.out.println("The variable using the lambda equals: " + x);
		};
		oldRunnable.run();
		lambdaRunnable.run();
	}
}

因为java.util.Runnable是一个功能接口,实现接口之类的样板式的代码能够使用lamdba替换。Runnable里的抽象方法是无參数所以 參数列表是一对空的括号().

Runnable assignment = () -> {expression or statements};

假设你写过JavaSE的界面或者写过Android的代码,你可能会知道点击一个button的时候时候处理的方法里面有定义一个匿名的内部类,并对当中的方法进行实现,来处理button点击触发的动作。接下来我们讲讲怎样用lamdba表达式来代替这个繁冗的内部类实现代码。

003

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;

public class ReplacingAnonymousInnerClasses {

	public static void main(String[] args) {
		Button btn = new Button();
		/**
		 * typical
		 */
		btn.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent e) {
				System.out.println("Do something... typical");
			}
		});
		/**
		 * lambda
		 */
		btn.setOnAction(e ->{
			System.out.println("Do something... lambda");
		});
	}

}

003演示样例中:我们定义了一个button,为buttonbtn设置点击事件。

setOnAction,里面对button点击操作处理。

新建一个匿名类,然后实现当中的handle方法,很复杂,而接下来的演示样例中看到我们能够使用lamdba轻松搞定。

Lamdba表达式还能作为參数传递到方法中使用。

比方我要计算一个集合List<Double>每一个元素的乘积,通过以上的学习我们我们能够非常easy的写出这个功能:

004

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

public class Test {

	private static Double multiplyNum = 1d;

	public static void main(String[] args) {

		Function<List<Double>, Double>  multiply = doubleList -> {
			doubleList.stream().forEach(num -> multiplyNum *= num);
			return multiplyNum;
		};
		List<Double> list = new ArrayList<>();
		list.add(12.3);
		list.add(25.6);
		list.add(38.4);
		multiply.apply(list);
		System.out.println(multiplyNum.intValue());
	}

}

ps:上面使用Function定义了Lamdba表达式用以计算集合元素的乘积,这里有一点注意。假设 multiplyNum定义在Main中,而不是在类的局部变量。那这里就会报错,Lamdba中在一个封闭范围内的变量必须是final或者表现是final的。你不能更改它的值。

Ok,写好了计算的方法,我们定义一个函数用以接收一个Lamdba表达式,以及要计算的元素集,然后返回计算的结果,方法例如以下:

005

public Double calculate(Function<List<Double>, Double> f1,Double[] args){
	Double returnValue;
	List<Double> varList = new ArrayList<>();
	int idx = 0;
	while (idx < args.length){
		varList.add(args[idx]);
		idx++;
	}
	returnValue = f1.apply(varList);
	return returnValue;
}

接下来加上Lamdba的实现并測试吧!

public class PassingLambdaFunctions {

	public Double calculate(Function<List<Double>, Double> f1,Double[] args){
		//见005,此处省略
	}

	public static void main(String[] args) {
		double x = 16.0;
		double y = 30.0;
		double z = 4.0;
		Function<List<Double>, Double> volumeCalc = list -> {
			if (list.size() == 3) {
				return list.get(0) * list.get(1) * list.get(2);
			} else {
				return Double.valueOf("-1");
			}
		};
		Double[] argList = new Double[3];
		argList[0] = x;
		argList[1] = y;
		argList[2] = z;
		Function<List<Double>, Double> areaCalc = list -> {
			if (list.size() == 2) {
				return list.get(0) * list.get(1);
			} else {
				return Double.valueOf("-1");
			}
		};
		Double[] argList2 = new Double[2];
		argList2[0] = x;
		argList2[1] = y;
		PassingLambdaFunctions p1 = new PassingLambdaFunctions();
		System.out.println("The volume is: " + p1.calculate(volumeCalc, argList));
		System.out.println("The area is: " + p1.calculate(areaCalc, argList2));
	}

}

不论什么类型的功能都能够使用Lamdba实现然后传递给不同的对象使用。这样能够更加提高代码的复用性&可维护性。Lamdba就说到这。假设不认为这些还不能满足你的需求,能够到官网去查找更详情的代码。或者搜索你想要的内容。

ps:本文演示样例引自 Josh Juneau所著 Java 8 Recipes, 2nd Edition

mission completed!

O(∩_∩)O~

时间: 2024-10-06 20:44:22

Java8 Lamdba表达式 003的相关文章

Java8 Lamdba表达式 002

本篇将讲述lamdba表达式的排序,本例包含一个Player对象的集合[稍后定义],通过每个player的分数高低对列表的player进行排序,类定义001如下 public class SortingPlayer { public static void main(String[] args) { List<Player> playerList = new ArrayList<>(); playerList.add(new Player("Black", &q

Java8 Lamdba表达式 001

在一个已经存在的编程语言里非常少有对现有的生态系统起重大影响的新特性.Lambda表达式对于Java语言就是这样的意义的存在.简单来说,Lambda表达式提供了便利的方式去创建一个匿名的功能.提供了一个简单的方式使用表达式或一系列的状态创建一个简单方法.Lambda表达式是包括一个抽象方法的接口.Lamdba表达式能够用来创建简单的匿名功能来实现对集合元素的排序和过滤,还能分配变量并传递到其它对象中.等等.以下将结合样例来加深大家对Lamdba的理解. 首先讲一下安装配置 要想使用Lamdba,

Java8 Lambda表达式深入学习(4) -- Java8实现方式

前几篇文章讨论了函数式接口和Lambda表达式语法.invokedynamic指令,以及Groovy2如何利用indy指令.本篇文章在前面几篇的基础之上,简要介绍Java8底层是如何实现Lambda表达式的. 示例代码 本文将以下面的代码为例展开讨论: import java.util.Arrays; import java.util.List; public class LambdaImplTest { public static void main(String[] args) { m1(A

java8 lambda表达式初接触

环境是jdk8 代码如下: package memTest; /** * Created by PC on 2014/8/5. */ public class LambdaOne { public static void test(){ new Thread(()-> System.out.print("hi") ).start(); } public static void main(String[] args) { new LambdaOne().test(); } } ja

深入学习Java8 Lambda表达式 -- 从函数式接口说起

希望本文能够成为Java8 Lambda表达式的快速入门指南. 函数式接口 理解Functional Interface(函数式接口,以下简称FI)是学习Java8 Lambda表达式的关键所在,所以放在最开始讨论.FI的定义其实很简单:任何接口,如果只包含唯一一个抽象方法,那么它就是一个FI.为了让编译器帮助我们确保一个接口满足FI的要求(也就是说有且仅有一个抽象方法),Java8提供了@FunctionalInterface注解.举个简单的例子,Runnable接口就是一个FI,下面是它的源

c#Lamdba表达式与托付

介绍: "Lambda表达式"(lambda expression)是一个匿名函数,在C#3.0中引入了lambda表达式,它是对匿名函数的一种简化,能够包括表达式和语句,而且可用于创建托付或表达式文件夹树类型. 怎样创建 格式:( 形參列表 ) => { 函数体 } 若要创建 Lambda表达式,须要在 Lambda运算符=>左側指定输入參数(假设有),然后在还有一側输入表达式或语句块.比如,lambda表达式 x => x * x指定名为 x的參数并返回 x的平方

回调与Java8的λ表达式

[9.3.1 回调]中,介绍了回调和<a target=_blank href="http://blog.csdn.net/yqj2065/article/details/8758101">好莱坞原则 (Java中)回调与通常的(遵循OCP 代码的)非回调代码,使用的技术不过是动态绑定/多态. 回调与通常的非回调代码,从类图和其自身代码上,没有区别. 之所以需要回调callback.隐式调用Implicit invocation(某些软件架构的作者使用的术语),是因为分层结

c#Lamdba表达式与委托

介绍: "Lambda表达式"(lambda expression)是一个匿名函数,在C#3.0中引入了lambda表达式,它是对匿名函数的一种简化,可以包含表达式和语句,并且可用于创建委托或表达式目录树类型. 如何创建 格式:( 形参列表 ) => { 函数体 } 若要创建 Lambda表达式,需要在 Lambda运算符=>左侧指定输入参数(如果有),然后在另一侧输入表达式或语句块.例如,lambda表达式 x => x * x指定名为 x的参数并返回 x的平方值.

java8 lambda表达式的一些用法

用 lamdba 表达式操作 对象集合的比较 优雅.代码也比较简洁. 希望大家掌握(可以避免写foreach 循环). 下面是实例代码(入门级,需要高级应用,自己得百度或者研究了) /** * Project Name:test * File Name:myTest.java * Package Name:test * Date:2016年8月15日下午5:39:50 * Copyright (c) 2016, [email protected] All Rights Reserved. * *