解决的问题:

behavior parameterization,即可以把一段code,逻辑作为参数传入;

这样做的目的,当然为了代码抽象和重用,把变化的逻辑抽象出去;

在java中,如果要实现behavior parameterization,需要通过传入类对象的方式,你首先要声明很多类,verbose

就算你用匿名类的方式,也会大大影响代码的可读性

所以lambda,是function programing的元素,可以将一个匿名函数作为参数传入

Lambdas

A lambda expression can be understood as a concise representation of an anonymous function that can be passed around

 Anonymous— We say anonymous because it doesn’t have an explicit name like a method would normally have: less to write and think about!
 Function— We say function because a lambda isn’t associated with a particular class like a method is. But like a method, a lambda has a list of parameters, a body, a return type, and a possible list of exceptions that can be thrown.
 Passed around— A lambda expression can be passed as argument to a method or stored in a variable.
 Concise— You don’t need to write a lot of boilerplate like you do for anonymous classes.

在什么地方可以使用lamda?

So where exactly can you use lambdas? You can use a lambda expression in the context of a functional interface.

In a nutshell, a functional interface is an interface that specifies exactly one abstract method.

可以看到lambda在用法上和匿名类是等价的

Function descriptor

在java8中,有多少种functional interface,
其中function description表示functional的signature,比如Consumer,参数T,无返回值

Predicate,典型的filter场景

The java.util.function.Predicate<T> interface defines an abstract method named test that accepts an object of generic type T and returns a boolean.

Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);

Consumer,消费者场景

The java.util.function.Consumer<T> interface defines an abstract method named accept that takes an object of generic type T and returns no result (void).

Function,transform场景

The java.util.function.Function<T, R> interface defines an abstract method named apply that takes an object of generic type T as input and returns an object of generic type R.

Type inference

用于编译器会做类型check和推导,所以你可以省略参数类型

Using local variables,弱版闭包

int portNumber = 1337;
Runnable r = () -> System.out.println(portNumber)

看到lambda,使用临时变量

They’re called capturing lambdas

和闭包的不同是,他有限制,

Lambdas are allowed to capture (that is, to reference in their bodies) instance variables and static variables without restrictions.
But local variables have to be explicitly declared final or are effectively final.

In other words, lambda expressions can capture local variables that are assigned to them only once.

这样会报错,因为你多次修改

我的理解,其实你改不改,对于Java的实现是没有问题,反正都是在你引用的时候,产生一份copy

但是如果你修改了值,容易产生歧义,你会期望引用的值变成你改的值,其实不会

Method references

Method references let you reuse existing method definitions and pass them just like lambdas.

In some cases they appear more readable and feel more natural than using lambda expressions.

You can think of method references as syntactic sugar for lambdas that refer only to a single method because you write less to express the same thing.

一种用于更简单的表示lambda的语法糖

Recipe for constructing method references

There are three main kinds of method references:

1. A method reference to a static method (for example, the method parseInt of Integer, written Integer::parseInt)

2. A method reference to an instance method of an arbitrary type (for example, the method length of a String, written String::length)

3. A method reference to an instance method of an existing object (for example, suppose you have a local variable expensiveTransaction that holds an object of type Transaction, which supports an instance method getValue; you can write expensiveTransaction::getValue)

Constructor references

You can create a reference to an existing constructor using its name and the keyword new as follows: ClassName::new. It works similarly to a reference to a static method.

注意,Apple::new,不是调用new,这个是产生一个function interface,supplier

对于带参数的构造函数,生成的就是function

Useful methods to compose lambda expressions

Composing Comparators

Composing Predicates

Composing Functions

Streams API

To summarize, the Streams API in Java 8 lets you write code that’s

 Declarative— More concise and readable

 Composable— Greater flexibility

 Parallelizable— Better performance

说白,就是以function programming的方式去处理collection,不需要显式的去写迭代,所以declarative

并且,可以透明的处理并行化问题

Streams vs. collections

Working with streams

To summarize, working with streams in general involves three items:

 A data source (such as a collection) to perform a query on

 A chain of intermediate operations that form a stream pipeline

 A terminal operation that executes the stream pipeline and produces a result

Intermediate operations such as filter or sorted return another stream as the return type.

This allows the operations to be connected to form a query. What’s important is that intermediate operations don’t perform any processing until a terminal operation is invoked on the stream pipeline—they’re lazy.

Numeric streams

Mapping to a numeric stream

The most common methods you’ll use to convert a stream to a specialized version are mapToInt, mapToDouble, and mapToLong.

这样可以直接用sum

和下面的写法比较一下,

Converting back to a stream of objects

Numeric ranges

Building streams

Streams from values

Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");

Stream<String> emptyStream = Stream.empty();

Streams from arrays

Streams from files

Streams from functions: creating infinite streams

Collecting data with streams

Collectors as advanced reductions

List<Transaction> transactions = transactionStream.collect(Collectors.toList());

Parallel data processing and performance

通过parallel来打开并行

sequential(),可以切换到串行

这里的并行是由fork/join来实现的

fork/join framework

The fork/join framework was designed to recursively split a parallelizable task into smaller tasks and then combine the results of each subtask to produce the overall result.

可以理解成local的map reduce

It’s an implementation of the ExecutorService interface, which distributes those subtasks to worker threads in a thread pool, called ForkJoinPool.

在java7中,我要这样写fork/join应用,比如一个简单的并行求和

注意在compute中,我们会判断阈值,如果不满足,就不断的二分,并递归的调用

然后,这样调用

public static long forkJoinSum(long n) {
long[] numbers = LongStream.rangeClosed(1, n).toArray();
ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers);
return new ForkJoinPool().invoke(task);
}

Spliterator

这是对fork逻辑的抽象

Java 8 already provides a default Spliterator implementation for all the data structures included in its Collections Framework.
Collections now implements the interface Spliterator, which provides a method spliterator.

在Java8中,所有Collections都是实现Spliterator接口

public interface Spliterator<T> {
boolean tryAdvance(Consumer<? super T> action);
Spliterator<T> trySplit();
long estimateSize();
int characteristics();
}

The algorithm that splits a Stream into multiple parts is a recursive process and proceeds as shown in figure 7.6.

split的过程就是不断的调用trySplit

实现WordCount功能的Spliterator

Default methods

Interface如果发生改变,增加function,那么所有实现该interface的类都需要修改以实现新的function,这个太烦躁了;

所以在Java8,给interface加了default methods

Using Optional as a better alternative to null

大家是不是都被NullPointerException烦的不行

需要写出这样丑陋的代码

Java 8 introduces a new class called java.util.Optional<T> that’s inspired by the ideas of Haskell and Scala.

Object value = map.get("key");

写成,

Optional

也可以写成这样,

区别就是of会抛异常

option支持的操作

开始的例子,可以写成,

Java8 in action的更多相关文章

  1. JAVA8 in Action:行为参数化,匿名类及lambda表达式的初步认知实例整理

    import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.functio ...

  2. Java8 in action(1) 通过行为参数化传递代码--lambda代替策略模式

    [TOC] 猪脚:以下内容参考<Java 8 in Action> 需求 果农需要筛选苹果,可能想要绿色的,也可能想要红色的,可能想要大苹果(>150g),也可能需要红的大苹果.基于 ...

  3. Java8 (1)

    参考资料: <Java8 in Action> Raoul-Gabriel Urma 一.jdk8 客观的说,Java8是一次有重大演进的版本,甚至很多人认为java8所做的改变,在许多方 ...

  4. Java8学习(4)-Stream流

    Stream和Collection的区别是什么 流和集合的区别是什么? 粗略地说, 集合和流之间的差异就在于什么时候进行计算.集合是一个内存中的数据结构,它包含数据结构中目前所有的值--集合中的每个元 ...

  5. Java8中的流操作-基本使用&性能测试

    为获得更好的阅读体验,请访问原文:传送门 一.流(Stream)简介 流是 Java8 中 API 的新成员,它允许你以声明式的方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).这有点儿 ...

  6. 《Java 8 in Action》Chapter 4:引入流

    1. 流简介 流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).就现在来说,你可以把它们看成遍历数据集的高级迭代器.此外,流还可以透明地并行 ...

  7. JAVA8初探-让方法参数具备行为能力并引入Lambda表达式

    关于JAVA8学习的意义先来贴一下某网站上的对它的简单介绍:“Java 8可谓Java语言历史上变化最大的一个版本,其承诺要调整Java编程向着函数式风格迈进,这有助于编写出更为简洁.表达力更强,并且 ...

  8. 全网最通透的Java8版本特性讲解

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  9. 专治不会看源码的毛病--spring源码解析AOP篇

    昨天有个大牛说我啰嗦,眼光比较细碎,看不到重点.太他爷爷的有道理了!要说看人品,还是女孩子强一些.原来记得看到一个男孩子的抱怨,说怎么两人刚刚开始在一起,女孩子在心里就已经和他过完了一辈子.哥哥们,不 ...

随机推荐

  1. 基于mindwave脑电波进行疲劳检测算法的设计(5)

    时隔两个多月了,前段时间在弄Socket,就没有弄这个了.现在好了,花了几天的时间,终于又完成了一小部分了.这一小节主要讲α,β,δ,θ等等波段之间的关系.废话不多说,直接给出这几天的成果. 上一次, ...

  2. Python list 常用方法总结

    一,创建列表  只要把逗号分隔的不同的数据项使用方括号([ ])括起来即可 下标(角标,索引)从0开始,最后一个元素的下标可以写-1 list  =  ['1',‘2,‘3’] list = [] 空 ...

  3. MXNET:欠拟合、过拟合和模型选择

    当模型在训练数据集上更准确时,在测试数据集上的准确率既可能上升又可能下降.这是为什么呢? 训练误差和泛化误差 在解释上面提到的现象之前,我们需要区分训练误差(training error)和泛化误差( ...

  4. Java编程的逻辑 (83) - 并发总结

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  5. 使用echo $? 查看命令是否执行成功

    shell中的特殊变量:变量名含义$0shell或shell脚本的名字$*以一对双引号给出参数列表$@将各个参数分别加双引号返回$#参数的个数$_代表上一个命令的最后一个参数$$代表所在命令的PID$ ...

  6. Java知多少(92)滚动条

    滚动条(JScrollBar)也称为滑块,用来表示一个相对值,该值代表指定范围内的一个整数.例如,用Word编辑文档时,编辑窗右边的滑块对应当前编辑位置在整个文档中的相对位置,可以通过移动选择新的编辑 ...

  7. 【转帖】39个让你受益的HTML5教程

    39个让你受益的HTML5教程                    闲话少说,本文作者为大家收集了网上学习HTML5的资源,期望它们可以帮助大家更好地学习HTML5. 好人啊! 不过,作者原来说的4 ...

  8. Java如何与Web服务器连接?

    在Java编程中,如何与Web服务器连接? 以下示例演示如何使用net.Socket类的sock.getInetAddress()方法与Web服务器连接. package com.yiibai; im ...

  9. PHP最全笔记(五)(值得收藏,不时翻看一下)

    // 删除 方法1:将其值设置为空字符串 setcookie('user[name]', ''); 方法2:将目标cookie设为“已过期”状态. //将cookie的生存时间设置为过期,则生存期限与 ...

  10. Ubuntu上运行Blender,在控制台上查看运行结果

    1.首先在控制台打开Blender. 具体操作:找到Blender的安装路径,我的是:/home/lcx/下载/blender-2.78c-linux-glibc219-x86_64 $cd /hom ...