博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[书]java8函数式编程(1)
阅读量:4059 次
发布时间:2019-05-25

本文共 5661 字,大约阅读时间需要 18 分钟。

一:Learning

package testLambda;import java.awt.Button;import java.awt.event.ActionEvent;import java.util.EventListener;import java.util.function.BinaryOperator;import org.junit.Test;/** * @author zhangdi * @description Lambda */public class LambdaChapter1and2 {
public static void main(String[] args) { } /** * 2.1 辨别Lambda表达式 */ @SuppressWarnings("unused") @Test public static void recognizeLambda() { // 1.不包含参数,使用()表示,没有参数,该Lamdba表达式实现了Runnable接口,该接口也只有一个run方法,没有参数,返回类型为void Runnable NoArguments = () -> System.out.println("hello world"); // 2.该Lamdba表达式包含且只包含一个参数可省略参数的括号 ActionListener oneArgument = (event) -> System.out.println("button clicked"); ActionListener oneArgument2 = event -> System.out.println("button clicked"); // 3.可以使用{}将lamdba表达式的主体括起来;只有一行代码的lambda的表达式也可以使用大括号;用来明确表达式的开始与结束 Runnable multistatement = () -> { System.out.println("hello"); System.out.println("world"); }; // 4.lambda表达式也可以是包含多个参数的方法; BinaryOperator
add = (x, y) -> x + y; BinaryOperator
addExplicit = (Long x, Long y) -> x + y; } /** * 2.2 函数接口是只有一个抽象方法的接口,用作lambda表达式的类型 */ public static void 函数接口() { } /** * 2.3 引用值,而不是变量 * 既成事实上的 final 是指只能给该变量赋值一次。 换句话说, Lambda 表达式引用的是值,而不是变量 * Lambda 表达式中引用既成事实上的 final 变量 -->Lambda 表达式都是静态类型 */ public static void valueReference() { Button button = new Button(); String name = getUserName(); button.addActionListener(event -> System.out.println("hi " + name)); } private static String getUserName() { // TODO Auto-generated method stub return "test"; } /** * 2.4 ActionListener 接口: 接受 ActionEvent 类型的参数, 返回空 * * ActionListener 只有一个抽象方法: actionPerformed, 被用来表示行为: 接受一个参数, 返回空。 * 记住, 由于 actionPerformed 定义在一个接口里, 因此 abstract 关键字不是必需 的。 * 该接口也继承自一个不具有任何方法的父接口: EventListener。 */ public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent event); } /** *java中重要的函数接口 * 接口 参数 返回类型 示例 * Predicate
T boolean 这张唱片已经发行了吗 * Consumer
T void 输出一个值 * Function
T R 获得 Artist 对象的名字 * Supplier
None T 工厂方法 * UnaryOperator
T T 逻辑非( !) * BinaryOperator
(T, T) T 求两个数的乘积( *) * * 2.5类型推断 * Predicate 用来判断真假的函数接口 */ public static void 类型推断() { Predicate
atLeast5 = x -> x > 5; } //Predicate 接口的源码, 接受一个对象, 返回一个布尔值 public interface Predicate
{ boolean test(T t); } //略显复杂的类型推断 :类型推断系统相当智能, 但若信息不够, 类型推断系统也无能为力。 类型系统不会漫无边 //际地瞎猜, 而会中止操作并报告编译错误, 寻求帮助 ,如去掉Long,代码不会通过编译 BinaryOperator
addLongs = (x, y) -> x + y; //没有泛型, 代码则通不过编译}

java中重要的函数接口:

这里写图片描述
总结:
* Lambda 表达式是一个匿名方法, 将行为像数据一样进行传递。
* Lambda 表达式的常见结构: BinaryOperator add = (x, y) → x + y。
* Lambda表达式里引用的到的变量是final的,本质是值,不是变量。
* Lambda表达式的类型是个函数接口,即仅有一个抽象方法的接口。( 函数接口指仅具有单个抽象方法的接口, 用来表示 Lambda 表达式的类型。)

二: 练习

1. 请看例 2-15 中的 Function 函数接口并回答下列问题。
例 2-15 Function 函数接口

public interface Function
{ R apply(T t); }
a. 请画出该函数接口的图示。b. 若要编写一个计算器程序, 你会使用该接口表示什么样的 Lambda 表达式?c. 下列哪些 Lambda 表达式有效实现了 Function
x -> x + 1;    (x, y) -> x + 1;    x -> x == 1;
2. ThreadLocal Lambda 表达式。 Java 有一个 ThreadLocal 类, 作为容器保存了当前线程里局部变量的值。 Java 8 为该类新加了一个工厂方法, 接受一个 Lambda 表达式, 并产生一个新的 ThreadLocal 对象, 而不用使用继承, 语法上更加简洁。a. 在 Javadoc 或集成开发环境( IDE) 里找出该方法。b. DateFormatter 类是非线程安全的。 使用构造函数创建一个线程安全的 DateFormatter对象, 并输出日期, 如“ 01-Jan-1970”。3. 类型推断规则。 下面是将 Lambda 表达式作为参数传递给函数的一些例子。 javac 能正确推断出 Lambda 表达式中参数的类型吗? 换句话说, 程序能编译吗?a. Runnable helloWorld = () -> System.out.println("hello world");b. 使用 Lambda 表达式实现 ActionListener 接口:
JButton button = new JButton();    button.addActionListener(event ->    System.out.println(event.getActionCommand()));
c. 以如下方式重载 check 方法后, 还能正确推断出 check(x -> x > 5) 的类型吗?
interface IntPred {
boolean test(Integer value); } boolean check(Predicate
predicate); boolean check(IntPred predicate);

练习答案:

public class Chapter1And2_practice {
public static class Question1 {
//x -> x + 1; } public static class Question3 {
//a.yes //b.yes //c.no } /** * @author NSNP736 * @description Question2 */ public static class Question2 {
//lamada-by richard public final static ThreadLocal
formatter = ThreadLocal.withInitial(() -> new DateFormatter(new SimpleDateFormat("dd-MMM-yyyy"))); //Anonymous Inner Class -byzhangdi public final static ThreadLocal
formatter2 = ThreadLocal.withInitial( new Supplier
(){ @Override public DateFormatter get() { DateFormatter dateFormatter = new DateFormatter(new SimpleDateFormat("dd-MMM-yyyy")); return dateFormatter; }}); } @Test public void exampleInB() { Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, 1970); cal.set(Calendar.MONTH, Calendar.JANUARY); cal.set(Calendar.DAY_OF_MONTH, 1); //formatter String format1 = Question2.formatter.get().getFormat().format(cal.getTime()); //formatter2 ThreadLocal
formatter = Question2.formatter; DateFormatter dateFormatter = formatter.get(); Format format = dateFormatter.getFormat(); String format2 = format.format(cal.getTime()); assertEquals("01-一月-1970", format1); assertEquals("01-一月-1970", format2); }}
你可能感兴趣的文章
Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
查看>>
fastcgi_param 详解
查看>>
Nginx配置文件(nginx.conf)配置详解
查看>>
标记一下
查看>>
IP报文格式学习笔记
查看>>
autohotkey快捷键显示隐藏文件和文件扩展名
查看>>
Linux中的进程
查看>>
学习python(1)——环境与常识
查看>>
学习设计模式(3)——单例模式和类的成员函数中的静态变量的作用域
查看>>
自然计算时间复杂度杂谈
查看>>
当前主要目标和工作
查看>>
使用 Springboot 对 Kettle 进行调度开发
查看>>
一文看清HBase的使用场景
查看>>
解析zookeeper的工作流程
查看>>
搞定Java面试中的数据结构问题
查看>>
慢慢欣赏linux make uImage流程
查看>>
linux内核学习(7)脱胎换骨解压缩的内核
查看>>
以太网基础知识
查看>>
慢慢欣赏linux 内核模块引用
查看>>
kprobe学习
查看>>