# 《Java 8 实战》读书笔记
## 目录
第二部分 函数式数据处理
第4章 引入流
1.流的基本使用
2.数值流
3.构建流
第5章 使用流
1.中间操作和基本操作
2.flatMap的使用
3.归约
第6章 用流收集数据
1.预定义收集器
第三部分 高效的Java 8编程
第12章 新的日期和时间API
12.1 LocalDate、LocalTime、Instant、Duration、period
1.使用 LocalDate 和 LocalTime
2.使用LocalDateTime
3.时间间隔 Duration 或 Period
12.2 操纵、解析和格式化日期
1.操纵日期加减
2.使用TemporalAdjusters
3.日期格式解析
## 正文
## 第二部分 函数式数据处理
### 第4章 引入流
#### 1.流的基本使用
```java
// 基础数据类
public class Data {
public enum Type {MEAT, FISH, OTHER}
public static List menu = Arrays.asList(
new Dish("pork", false, 800, Type.MEAT),
new Dish("beef", false, 700, Type.MEAT),
new Dish("chicken", false, 400, Type.MEAT),
new Dish("french fries", true, 530, Type.OTHER),
new Dish("rice", true, 350, Type.OTHER),
new Dish("season fruit", true, 120, Type.OTHER),
new Dish("pizza", true, 550, Type.OTHER),
new Dish("prawns", false, 300, Type.FISH),
new Dish("salmon", false, 450, Type.FISH));
static class Dish {
private final String name;
private final boolean vegetarian;
private final int calories;
private final Data.Type type;
public Dish(String name, boolean vegetarian, int calories, Data.Type type) {
this.name = name;
this.vegetarian = vegetarian;
this.calories = calories;
this.type = type;
}
public String getName() {
return name;
}
public boolean isVegetarian() {
return vegetarian;
}
public int getCalories() {
return calories;
}
public Data.Type getType() {
return type;
}
@Override
public String toString() {
return name;
}
}
}
```
```java
// 流的使用
public class Stream {
public static void main(String[] args) {
List collect = Data.menu.stream().filter(d -> d.getCalories() > 300).map(Data.Dish::getName).limit(3).collect(Collectors.toList());
collect.forEach(System.out::println);
}
}
```
#### 2.数值流
**映射到数值流(mapToInt)**
```java
public class Stream {
public static void main(String[] args) {
//得到的是 Stream
java.util.stream.Stream integerStream = Data.menu.stream().map(Data.Dish::getCalories);
Integer reduce = integerStream.reduce(0, Integer::sum);
System.out.println(reduce); //4200
//得到的是 IntStream
IntStream intStream = Data.menu.stream().mapToInt(Data.Dish::getCalories);
int sum = intStream.sum();
System.out.println(sum); //4200
}
}
```
**数值流到映射(boxed)**
```java
public class Stream {
public static void main(String[] args) {
//得到的是 Stream
java.util.stream.Stream integerStream = Data.menu.stream().map(Data.Dish::getCalories);
Integer reduce = integerStream.reduce(0, Integer::sum);
System.out.println(reduce); //4200
//得到的是 IntStream
IntStream intStream = Data.menu.stream().mapToInt(Data.Dish::getCalories);
java.util.stream.Stream boxed = intStream.boxed();
Integer reduceSum = boxed.reduce(0, Integer::sum);
System.out.println(reduceSum); //4200
}
}
```
```java
// 收集器对流的消耗
public class Stream {
public static void main(String[] args) {
//得到的是 Stream
java.util.stream.Stream integerStream = Data.menu.stream().map(Data.Dish::getCalories);
Integer reduce = integerStream.reduce(0, Integer::sum);
System.out.println(reduce); //4200
//得到的是 IntStream
IntStream intStream = Data.menu.stream().mapToInt(Data.Dish::getCalories);
int sum = intStream.sum();
// 下面这行报错:IllegalStateException: stream has already been operated upon or closed
// 因为sum() 是一个终止流方法,会消耗掉流,所以调用 intStream.boxed() 方法时候会报错
java.util.stream.Stream boxed = intStream.boxed();
Integer reduceSum = boxed.reduce(0, Integer::sum);
System.out.println(sum); //4200
System.out.println(reduceSum); //4200
}
```
#### 3.构建流
**1.由值创建流**
```java
public class StreamCreate {
public static void main(String[] args) {
// 由值创建流
Stream stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);
// 创建空流
Stream