# Java 8 éå
³æ»ç¥
> ç¹èµ+æ¶è å°±å¦ä¼ç³»åï¼æç« æ¶å½å¨ GitHub [JavaEgg](https://github.com/Jstarfish/JavaEgg) ï¼N线äºèç½å¼åå¿
夿è½å
µå¨è°±
> Java8æ©å¨2014å¹´3æå°±åå¸äºï¼è¿ä¸å¾å
¨é¢äºè§£ä¸
>
> æ¬ææ¯ç¨ææå£çè±æåä¸è¦è¸çè¿ææé£ææï¼ç¬åºçï¼æ²¡ææ·±ç©¶æºç ï¼åªæ¯å¯¹ Java8 æä¸ä¸ªæ´ä½ç认ç¥ï¼å¯ä»¥ä¸æç¨èµ·æ¥ï¼ç¤ºä¾ä»£ç ä¹é½å¨githubä¸
# JDK 8 æä»ä¹æ°åè½
- Java ç¼ç¨è¯è¨ï¼ Java Programming Languageï¼
- **Lambda表达å¼**ï¼ä¸ä¸ªæ°çè¯è¨ç¹æ§ï¼ å®ä»¬ä½¿æ¨è½å¤å°å½æ°è§ä¸ºæ¹æ³åæ°ï¼æå°ä»£ç è§ä¸ºæ°æ®
- **æ¹æ³å¼ç¨**ï¼ æ¹æ³å¼ç¨ä¸ºå·²ç»æåç§°çæ¹æ³æä¾æäºé
读çlambda表达å¼
- **é»è®¤æ¹æ³**ï¼ä½¿ç¨ default å
³é®å为æ¥å£å®ä¹é»è®¤æ¹æ³ï¼æå®ç°çæ¹æ³ï¼
- **é夿³¨è§£**æä¾äºå°å䏿³¨è§£å¤æ¬¡åºç¨äºåä¸å£°ææç±»å使ç¨çè½å
- **ç±»åæ³¨è§£**æä¾äºå¨ä½¿ç¨ç±»åçä»»ä½å°æ¹åºç¨æ³¨è§£çè½åï¼èä¸ä»
ä»
æ¯å¨å£°æä¸
- Java8 å¢å¼ºäº**ç±»åæ¨æ**
- æ¹æ³åæ°åå°
- `java.util.function`: ä¸ä¸ªæ°çå
ï¼å®å
å«ä¸ºlambda表达å¼åæ¹æ³å¼ç¨æä¾ç®æ ç±»åçéç¨åè½æ¥å£
- éåï¼Collectionsï¼
- `java.util.stream`å
䏿°å¢äº **Stream API** ï¼ç¨æ¥æ¯æå¯¹å
ç´ æµç彿°å¼æä½
- æ¹è¿äºæé®å²çªé®é¢ç **HashMap**
- ç²¾ç®è¿è¡æ¶ï¼Compact Profilesï¼
- å®å
¨æ§ï¼Securityï¼
- JavaFX
- Toolsï¼å
å«ä¸äºè°ç¨Nashorn弿ã å¯å¨JavaFXåºç¨ç¨åºçç ï¼
- å½é
åï¼Internationalizationï¼
- Unicodeå¢å¼ºï¼å
æ¬å¯¹Unicode 6.2.0çæ¯æ
- æä¾äºæ°ç Calendar å Locale API
- é¨ç½²ï¼Deploymentï¼
- æ¥æ-æ¶é´ å
ï¼**Date-Time Package**ï¼ï¼æä¾äºæ´å
¨é¢çæ¶é´åæ¥ææä½
- èæ¬ï¼Scriptingï¼ï¼Java 8æä¾äºä¸ä¸ªæ°ç Nashorn javascript 弿(å代äºNashorn javascript弿)ï¼å®å
许æä»¬å¨JVMä¸è¿è¡ç¹å®ç javascript åºç¨
- æ¹è¿ IO å NIO
- æ¹è¿ `java.lang` å `java.util`
- æ¯ææ°ç»å¹¶è¡æåº
- æ¯æBase64 çç¼ç åè§£ç
- æ¯æ æ 符å·è¿ç®
- **Optional ç±»** ï¼æå¤§ååå°ç©ºæéå¼å¸¸
- JDBC
- JDBC-ODBC桥已被移é¤
- JDBC 4.2å¼å
¥äºæ°çç¹æ§
- Java DBï¼ä¸ä¸ªJavaæ°æ®åºï¼
- ç½ç»ï¼Networkingï¼
- æ°å¢äº `java.net.URLPermission`
- å¹¶åï¼**Concurrency**ï¼
- `CompletableFuture` å¢å¼ºäºä¹åç`Future`
- `java.util.concurrent.ConcurrentHashMap` æ¯æåºäºæ°æ·»å çstreamsåè½ålambda表达å¼çèåæä½
- `java.util.concurrent.atomic` æä¾äºä¸ç»åååéç±»ï¼ å¯¹äºå个åéæ¯ææ éã线ç¨å®å
¨æä½çå·¥å
·ç±»
- `java.util.concurrent.ForkJoinPool` ç¨äºè¡¥å
ExecutorService
- `java.util.concurrent.locks.StampedLock` æä¾äºåºäºåè½çéï¼æä¸ç§æ¨¡å¼ç¨äºæ§å¶è¯»/å访é®
- JVM: ç§»é¤äº PermGen ï¼åè代ä¹çæ¯Metaspace
Java8 ç¹å«å¼ºå¤§çæ¯Lambda 表达å¼åStreamï¼éè¿å®ä¸¤æ°å¢åå¢å¼ºäºå¾å¤å
æ°å¢ï¼ `java.lang.invoke`ã` java.util.function`ã`java.util.stream`
ä¿®æ¹ï¼

------
## ä¸ãLambda表达å¼
å¯ä»¥æ Lambda 表达å¼ç解为**ç®æ´ç表示å¯ä¼ éçå¿å彿°çä¸ç§æ¹å¼**ï¼Lambda表达å¼åºäºæ°å¦ä¸ç**λæ¼ç®**å¾åï¼å®æ²¡æåç§°ï¼ä½æåæ°å表ã彿°ä¸»ä½ãè¿åç±»åï¼å¯è½è¿æä¸ä¸ªå¯ä»¥æåºçå¼å¸¸å表ã
- å¿åââå¿å彿°ï¼å³æ²¡æå½æ°åç彿°ï¼ï¼ä¸åæ®éçæ¹æ³æä¸ä¸ªæç¡®çåç§°ï¼âåå¾å°ï¼æ³å¾å¤â
- 彿°ââLambda彿°ä¸åæ¹æ³é£æ ·å±äºæä¸ªç¹å®çç±»ï¼ä½ä¸æ ·æåæ°å表ã彿°ä¸»ä½åè¿åç±»å
- ä¼ éââLambda表达å¼å¯ä»¥ä½ä¸ºåæ°ä¼ éç»æ¹æ³æè
åå¨å¨åéä¸
- ç®æ´ââæ éåå¿åç±»é£æ ·åå¾å¤æ¨¡æ¿ä»£ç
Lambda表达å¼ä½¿æ¨è½å¤å°è£
å个è¡ä¸ºåå
å¹¶å°å
¶ä¼ éç»å
¶ä»ä»£ç ã妿叿坹éåçæ¯ä¸ªå
ç´ ãæµç¨å®ææ¶ææµç¨éå°éè¯¯æ¶æ§è¡æä¸ªæä½ï¼å¯ä»¥ä½¿ç¨lambda表达å¼ã
### 1. 为ä»ä¹è¦ä½¿ç¨Lambda表达å¼
Lambda æ¯ä¸ä¸ªå¿å彿°ï¼æä»¬å¯ä»¥æ Lambda表达å¼ç解为æ¯ä¸æ®µå¯ä»¥ä¼ éç代ç (**å°ä»£ç åæ°æ®ä¸æ ·è¿è¡ä¼ é**ââ**è¡ä¸ºåæ°å**)ãå¯ä»¥ååºæ´ç®æ´ãæ´çµæ´»ç代ç ãä½ä¸ºä¸ç§æ´ç´§åç代ç 飿 ¼ï¼ä½¿Javaçè¯è¨è¡¨è¾¾è½åå¾å°äºæåã
å¿åç±»çä¸ä¸ªé®é¢æ¯ï¼å¦ææ¨çå¿åç±»çå®ç°é常ç®åï¼ä¾å¦ä¸ä¸ªæ¥å£åªå
å«ä¸ä¸ªæ¹æ³ï¼é£ä¹å¿åç±»çè¯æ³å¯è½çèµ·æ¥å¾ç¬¨æå䏿¸
æ¥ãå¨è¿äºæ
åµä¸ï¼æ¨é常è¯å¾å°åè½ä½ä¸ºåæ°ä¼ éç»å¦ä¸ä¸ªæ¹æ³ï¼ä¾å¦å½æäººå廿鮿¶åºè¯¥éåä»ä¹æä½ãLambda表达å¼å
许æ¨è¿æ ·åï¼å°åè½è§ä¸ºæ¹æ³åæ°ï¼æå°ä»£ç è§ä¸ºæ°æ®ã

### 2. Lambda 表达å¼è¯æ³
`(parameters) -> expression` æ`(parameters) ->{ statements; }`
Lambda 表达å¼å¨ Java è¯è¨ä¸å¼å
¥äºä¸ä¸ªæ°çè¯æ³å
ç´ åæä½ç¬¦ãè¿ä¸ªæä½ç¬¦ä¸º â**->**â ï¼ è¯¥æä½ç¬¦è¢«ç§°ä¸º **Lambda æä½ç¬¦**æåªå¤´æä½ç¬¦ãå®å° Lambda å为两个é¨åï¼
- å·¦ä¾§ï¼æå®äº Lambda 表达å¼éè¦çææåæ°
- å³ä¾§ï¼æå®äº Lambda ä½ï¼å³ Lambda 表达å¼è¦æ§è¡çåè½
#### eg(é误示è)ï¼
```java
(Integer i) -> return "hello"+i; //é误çLambdaï¼returnæ¯ä¸ä¸ªæ§å¶æµè¯å¥ï¼éè¦{}
(String s) -> {"hello";} //âhelloâæ¯ä¸ä¸ªè¡¨è¾¾å¼ï¼ä¸æ¯è¯å¥ï¼ä¸éè¦{}ï¼å¯ä»¥åæ{return âhelloâ;}
```
#### eg(æ£ç¡®ç¤ºè)ï¼
1. æ åï¼æ è¿åå¼ï¼Lambda ä½åªé䏿¡è¯å¥
```java
Runnable runnable = () -> System.out.println("hello lambda");
```
2. Lambda éè¦ä¸ä¸ªåæ°
```java
Consumer consumer = (args) -> System.out.println(args);
```
Lambda åªéè¦ä¸ä¸ªåæ°æ¶ï¼åæ°çå°æ¬å·å¯ä»¥çç¥
```java
Consumer consumer = args -> System.out.println(args);
```
3. Lambda éè¦ä¸¤ä¸ªåæ°ï¼å¹¶ä¸æè¿åå¼
```java
BinaryOperator binaryOperator = (Long x,Long y) -> {
System.out.println("å®ç°å½æ°æ¥å£æ¹æ³");
return x +y;
};
```
åæ°çæ°æ®ç±»åå¯çç¥ï¼Java8å¢å¼ºäº**ç±»åæ¨æ**ï¼ä¸å½ Lambda ä½åªæä¸æ¡è¯å¥æ¶ï¼return ä¸å¤§æ¬å·å¯ä»¥çç¥
```java
BinaryOperator binaryOperator = (x, y) -> x + y;
```
**ç±»åæ¨æ**
ä¸è¿° Lambda 表达å¼ä¸çåæ°ç±»å齿¯ç±ç¼è¯å¨æ¨æå¾åºçãLambda 表达å¼ä¸æ éæå®ç±»åï¼ç¨åºä¾ç¶å¯ä»¥ç¼è¯ï¼è¿æ¯å 为 javac æ ¹æ®ç¨åºçä¸ä¸æï¼å¨åå°æ¨æåºäºåæ°çç±»åãLambda 表达å¼çç±»åä¾èµäºä¸ä¸æç¯å¢ï¼æ¯ç±ç¼è¯å¨æ¨æåºæ¥çãè¿å°±æ¯æè°çâç±»åæ¨æâãJava7ä¸å¼å
¥ç**è±å½¢è¿ç®ç¬¦**ï¼**<>**ï¼,å°±æ¯å©ç¨æ³åä»ä¸ä¸ææ¨æç±»åã
```java
List list = new ArrayList<>();
```
### 3. Lambda表达å¼å®ä¾
宿¹æä¾ç示ä¾ï¼åè®¾ä½ è¦å¼åä¸ä¸ªç¤¾äº¤è½¯ä»¶ï¼é£ä¸ªç¼ºæçPMæå¤©æ¹éæ±ï¼ä»å¤©è¦æ¥è¯¢åºæå¹´ç¨æ·çä¿¡æ¯ï¼æå¤©åè¦æ¥è¯¢æå¹´å¥³æ§çç¨æ·ä¿¡æ¯ï¼å天åè¦æåç§å¥æªçæç´¢æ¡ä»¶æ¥è¯¢ã
è¿æ¶çç¨åºåï¼ä»ç®åçç¨æ·éåæ¯è¾æ¹æ³æ¹ä¸ºéç¨çæç´¢æ¹æ³å°åæ¥é½ç¨ä¸äºå·¥å模å¼ï¼çå°ç¬¬7å¤©çæ¶åï¼ä½ ä¸èç¦äºï¼çå¾·ï¼æ¯ä¸ªæ¡ä»¶å°±ä¸å¥è¯ï¼æåäº7ä¸ªç±»ï¼æå¯ä¸æ³å`CtrlCVå·¥ç¨å¸`ï¼è¿æ¶åLambdaè¡¨è¾¾å¼æ¯ä½ çä¸äºä¹éã
**è¡ä¸ºåæ°å**å°±æ¯å¯ä»¥å¸®å©ä½ å¤çé¢ç¹åæ´çéæ±çä¸ç§è½¯ä»¶å¼å模å¼ã
宿¹æä¾çdemoï¼ä¸æ¥æ¥åè¯ä½ 使ç¨Java8ç好å¤ï¼ä»å¼åæ°åå°è¡ä¸ºåæ°åï¼ã[代ç ](https://github.com/Jstarfish/starfish-learning/tree/master/starfish-learn-java8/src/lambda)
```java
import java.util.List;
import java.util.ArrayList;
import java.time.chrono.IsoChronology;
import java.time.LocalDate;
public class Person {
public enum Sex {
MALE, FEMALE
}
String name;
LocalDate birthday;
Sex gender;
String emailAddress;
Person(String nameArg, LocalDate birthdayArg,
Sex genderArg, String emailArg) {
name = nameArg;
birthday = birthdayArg;
gender = genderArg;
emailAddress = emailArg;
}
public int getAge() {
return birthday
.until(IsoChronology.INSTANCE.dateNow())
.getYears();
}
public void printPerson() {
System.out.println(name + ", " + this.getAge());
}
public Sex getGender() {
return gender;
}
public String getName() {
return name;
}
public String getEmailAddress() {
return emailAddress;
}
public LocalDate getBirthday() {
return birthday;
}
public static int compareByAge(Person a, Person b) {
return a.birthday.compareTo(b.birthday);
}
public static List createRoster() {
List roster = new ArrayList<>();
roster.add(new Person(
"Fred",
IsoChronology.INSTANCE.date(1980, 6, 20),
Person.Sex.MALE,
"[email protected]"));
roster.add(new Person(
"Jane",
IsoChronology.INSTANCE.date(1990, 7, 15),
Person.Sex.FEMALE, "[email protected]"));
roster.add(new Person(
"George",
IsoChronology.INSTANCE.date(1991, 8, 13),
Person.Sex.MALE, "[email protected]"));
roster.add(new Person(
"Bob",
IsoChronology.INSTANCE.date(2000, 9, 12),
Person.Sex.MALE, "[email protected]"));
return roster;
}
}
```

```java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
public class RosterTest {
interface CheckPerson {
boolean test(Person p);
}
/**
* 1. egï¼è¾åºå¹´é¾å¤§äº20å²çæå
* å¹é
符åæä¸ç¹å¾çæåçæ¹æ³
* å¦æèæ¿è¦å¹´é¾å¨æä¸åºé´çæåå¢ï¼æ¥çæ¢æ¹æ³
*/
public static void printPersonsOlderThan(List roster, int age) {
for (Person p : roster) {
if (p.getAge() >= age) {
p.printPerson();
}
}
}
/**
* 2. eg:è¾åºå¹´é¾å¨14å°30å²ä¹é´çæå
* æ´å
¨é¢çå¹é
æ¹æ³
* å¦æèæ¿åªè¦ç·æ§æåå¢ï¼
*/
public static void printPersonsWithinAgeRange(
List roster, int low, int high) {
for (Person p : roster) {
if (low <= p.getAge() && p.getAge() < high) {
p.printPerson();
}
}
}
/**
* 3. eg:èæ¿åæåºäºåç§å¤æçéæ±ï¼ä¸è¦å¤å¥³åº§çãåªè¦é®ç®±æ¯163çï¼æä¹æï¼
* æ¹æ³1ï¼å¨æ¬å°ç±»ä¸æå®æç´¢æ¡ä»¶ä»£ç ï¼éè¿æ¥å£æ¹å¼ï¼ä¸åç鿱坹åºä¸åçå®ç°ç±»ï¼
* æ¯æ¬¡é½è¦æ°å»ºå®ç°ç±»ï¼å大éç代ç
* æ¹æ³2ï¼å¨å¿åç±»ä¸æå®æç´¢æ¡ä»¶ä»£ç ï¼ä¸éè¦ååç§å®ç°ï¼ä½æ¯è¿è¦å个interface CheckPersonï¼
* èä¸å¿åç±»åèµ·æ¥ä¹æºéº»ç¦
* æ¹æ³3ï¼Lambdaè¡¨è¾¾å¼æ¯æäººçä¸äºä¹éï¼CheckPersonæ¯ä¸ä¸ªåªå
å«ä¸ä¸ªæ½è±¡æ¹æ³çæ¥å£ï¼
* æ¯è¾ç®åï¼Lambdaå¯ä»¥çç¥å
¶å®ç°
*/
public static void printPersons(
List roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
/**
* 4. eg: æè¿ä¹ä¹
ï¼è¿å¾åä¸ä¸ªæ¥å£ï¼è䏿¯åªæä¸ä¸ªæ½è±¡æ¹æ³ï¼è¿æ¯ä¸ç½ï¼
* ä½ ä¹å¯ä»¥ä½¿ç¨æ åç彿°æ¥å£æ¥ä»£æ¿æ¥å£CheckPersonï¼ä»èè¿ä¸æ¥åå°æéç代ç é
* java.util.functionå
ä¸å®ä¹äºæ åç彿°æ¥å£
* æä»¬å¯ä»¥ä½¿ç¨JDK8æä¾ç Predicateæ¥å£æ¥ä»£æ¿CheckPersonã
* 该æ¥å£å
嫿¹æ³boolean test(T t)
*/
public static void printPersonsWithPredicate(
List roster, Predicate tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
/**
* 5. Lambda表达å¼å¯ä¸åªæ¯è½å¤ç®åå¿åç±»
* ç®å p.printPerson(),
* 使ç¨Consumeræ¥å£çvoid accept(T t)æ¹æ³ï¼ç¸å½äºå
¥åçæä½
*/
public static void processPersons(
List roster,
Predicate tester,
Consumer block) {
for (Person p : roster) {
if (tester.test(p)) {
block.accept(p);
}
}
}
/**
* 6. eg: èæ¿è¯´äºåªæ³çå°é®ç®±
* Functionæ¥å£ï¼ç¸å½äºè¾å
¥ç±»åï¼mapperå®ä¹åæ°ï¼blockè´è´£æ¹å¯¹ç»å®çåæ°è¿è¡æ§è¡
*/
public static void processPersonsWithFunction(
List roster,
Predicate tester,
Function mapper,
Consumer block) {
for (Person p : roster) {
if (tester.test(p)) {
String data = mapper.apply(p);
block.accept(data);
}
}
}
// 7. ä½¿ç¨æ³å
public static void processElements(
Iterable source,
Predicate tester,
Function mapper,
Consumer block) {
for (X p : source) {
if (tester.test(p)) {
Y data = mapper.apply(p);
block.accept(data);
}
}
}
public static void main(String[] args) {
List roster = Person.createRoster();
/**
* 1. è¾åºå¹´é¾å¤§äº20å²çæå
*/
System.out.println("Persons older than 20:");
printPersonsOlderThan(roster, 20);
System.out.println();
/**
* 2. è¾åºå¹´é¾å¨14å°30å²ä¹é´çæå
*/
System.out.println("Persons between the ages of 14 and 30:");
printPersonsWithinAgeRange(roster, 14, 30);
System.out.println();
/**
* 3. è¾åºå¹´é¾å¨18å°25å²çç·æ§æå
* ï¼å¨æ¬å°ç±»ä¸æå®æç´¢æ¡ä»¶ï¼
* æ¨å¯ä»¥ä½¿ç¨ä¸ä¸ªå¿åç±»è䏿¯ä¸ä¸ªæ¬å°ç±»ï¼å¹¶ä¸ä¸å¿
为æ¯ä¸ªæç´¢å£°æä¸ä¸ªæ°ç±»
*/
System.out.println("Persons who are eligible for Selective Service:");
class CheckPersonEligibleForSelectiveService implements CheckPerson {
public boolean test(Person p) {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
}
// è¿ä¸ªå
¶å®å°±æ¯éè¿è¡ä¸ºåæ°åä¼ é代ç
printPersons(
roster, new CheckPersonEligibleForSelectiveService());
System.out.println();
// 3. å¨å¿åç±»ä¸æå®æç´¢æ¡ä»¶ä»£ç
System.out.println("Persons who are eligible for Selective Service " +
"(anonymous class):");
printPersons(
roster,
new CheckPerson() {
public boolean test(Person p) {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
}
);
System.out.println();
// 3: 使ç¨Lambda表达å¼ç®å代ç ï¼ä¸ä¸ªç®å¤´
System.out.println("Persons who are eligible for Selective Service " +
"(lambda expression):");
printPersons(
roster,
(Person p) -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
System.out.println();
// 4. 使ç¨Lambdaçæ ååè½æ¥å£
System.out.println("Persons who are eligible for Selective Service " +
"(with Predicate parameter):");
printPersonsWithPredicate(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
System.out.println();
//5.使ç¨PredicateåConsumeråæ°
System.out.println("5. Persons who are eligible for Selective Service " +
"(with Predicate and Consumer parameters):");
processPersons(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.printPerson()
);
System.out.println();
// 6. éè¿Function æå®è¾åºç±»å
System.out.println("Persons who are eligible for Selective Service " +
"(with Predicate, Function, and Consumer parameters):");
processPersonsWithFunction(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.getEmailAddress(),
email -> System.out.println(email)
);
System.out.println();
// 7. ä½¿ç¨æ³å
System.out.println("Persons who are eligible for Selective Service " +
"(generic version):");
processElements(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.getEmailAddress(),
email -> System.out.println(email)
);
System.out.println();
// 8: ä½¿ç¨æ¥åLambda表达å¼çæ¹éæ°æ®æä½
System.out.println("Persons who are eligible for Selective Service " +
"(with bulk data operations):");
roster.stream()
.filter(
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25)
.map(p -> p.getEmailAddress())
.forEach(email -> System.out.println(email));
System.out.println();
/**
* 9. æå¹´é¾æåºãJava 8 ä¹åéè¦å®ç° Comparator æ¥å£
* æ¥å£æ¯è¾å¨æ¯ä¸ä¸ªåè½æ¥å£ãå æ¤ï¼
* å¯ä»¥ä½¿ç¨lambdaè¡¨è¾¾å¼æ¥ä»£æ¿å®ä¹å¹¶å建ä¸ä¸ªå®ç°äºComparatorçç±»çæ°å®ä¾:
*/
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
Arrays.sort(rosterAsArray,
(a, b) -> Person.compareByAge(a, b)
);
for (Person person : roster) {
person.printPerson();
}
/**
* è¿ç§æ¯è¾ä¸¤ä¸ªPersonå®ä¾çåºçæ¥æçæ¹æ³å·²ç»ä½ä¸ºPerson.
* comparebyageåå¨ãä½ å¯ä»¥å¨lambda表达å¼ä¸è°ç¨è¿ä¸ªæ¹æ³
*/
Arrays.sort(rosterAsArray,
(a, b) -> Person.compareByAge(a, b)
);
}
```
------
## äºã彿°å¼æ¥å£
### 1. ä»ä¹æ¯å½æ°å¼æ¥å£
- åªå
å«ä¸ä¸ªæ½è±¡æ¹æ³çæ¥å£ï¼ç§°ä¸ºå½æ°å¼æ¥å£ï¼è¯¥æ½è±¡æ¹æ³ä¹è¢«ç§°ä¸ºå½æ°æ¹æ³ã æä»¬çç¥çComparatoråRunnableãCallableå°±å±äºå½æ°å¼æ¥å£ã
- è¿æ ·çæ¥å£è¿ä¹ç®åï¼é½ä¸å¼å¾å¨ç¨åºä¸å®ä¹ï¼æä»¥ï¼JDK8å¨ `java.util.function` ä¸å®ä¹äºå 个æ åç彿°å¼æ¥å£ï¼ä¾æä»¬ä½¿ç¨ã[Package java.util.function](https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html)
- å¯ä»¥éè¿ Lambda è¡¨è¾¾å¼æ¥å建该æ¥å£ç对象ãï¼è¥ Lambda è¡¨è¾¾å¼æåºä¸ä¸ªåæ£å¼å¸¸ï¼é£ä¹è¯¥å¼å¸¸éè¦å¨ç®æ æ¥å£çæ½è±¡æ¹æ³ä¸è¿è¡å£°æï¼ã
- æä»¬å¯ä»¥å¨ä»»æå½æ°å¼æ¥å£ä¸ä½¿ç¨ **@FunctionalInterface** æ³¨è§£ï¼ è¿æ ·åå¯ä»¥æ£æ¥å®æ¯å¦æ¯ä¸ä¸ªå½æ°å¼æ¥å£ï¼åæ¶ javadoc ä¹ä¼å
å«ä¸æ¡å£°æï¼è¯´æè¿ä¸ªæ¥å£æ¯ä¸ä¸ªå½æ°å¼æ¥å£ã
### 2. èªå®ä¹å½æ°å¼æ¥å£
```java
@FunctionalInterface //@FunctionalInterfaceæ æ³¨è¯¥æ¥å£ä¼è¢«è®¾è®¡æä¸ä¸ªå½æ°å¼æ¥å£ï¼å¦åä¼ç¼è¯é误
public interface MyFunc {
T getValue(T t);
}
```
```java
public static String toUpperString(MyFunc myFunc, String str) {
return myFunc.getValue(str);
}
public static void main(String[] args) {
String newStr = toUpperString((str) -> str.toUpperCase(), "abc");
System.out.println(newStr);
}
```
ä½ä¸ºåæ°ä¼ é Lambda 表达å¼ï¼ä¸ºäºå° Lambda 表达å¼ä½ä¸ºåæ°ä¼ éï¼**æ¥æ¶Lambda 表达å¼çåæ°ç±»åå¿
é¡»æ¯ä¸è¯¥ Lambda 表达å¼å
¼å®¹ç彿°å¼æ¥å£çç±»å**ã
彿°æ¥å£ä¸ºlambda表达å¼åæ¹æ³å¼ç¨æä¾ç®æ ç±»å
### 3. Java å
ç½®åå¤§æ ¸å¿å½æ°å¼æ¥å£
| 彿°å¼æ¥å£ | åæ°ç±»å | è¿åç±»å | ç¨é |
| ------------- | -------- | -------- | ------------------------------------------------------------ |
| Consumer\ | T | void | 对类å为Tç对象åºç¨æä½ï¼å
嫿¹æ³ï¼void accept(T t) |
| Supplier\ | æ | T | è¿åç±»å为Tç对象ï¼å
嫿¹æ³ï¼T get(); |
| Function | T | R | 对类å为Tç对象åºç¨æä½ï¼å¹¶è¿åç»æãç»ææ¯Rç±»åç对象ãå
嫿¹æ³ï¼R apply(T t); |
| Predicate\ | T | boolean | ç¡®å®ç±»å为Tç对象æ¯å¦æ»¡è¶³æçº¦æï¼å¹¶è¿å boolean å¼ãå
嫿¹æ³ boolean test(T t); |
```java
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
* Java8 å
ç½®çåå¤§æ ¸å¿å½æ°å¼æ¥å£
* Consumer : æ¶è´¹åæ¥å£ void accept(T t);
* Supplier : ä¾ç»åæ¥å£ T get();
* Function : 彿°åæ¥å£ R apply(T t);
* Predicate : æè¨åæ¥å£ boolean test(T t);
*/
public class FunctionalInterfaceTest {
//Predicate æè¨åæ¥å£ï¼å°æ»¡è¶³æ¡ä»¶çå符串æ¾å
¥éå
public List filterStr(List list, Predicate predicate) {
List newList = new ArrayList<>();
for (String s : list) {
if (predicate.test(s)) {
newList.add(s);
}
}
return newList;
}
@Test
public void testPredicate() {
List list = Arrays.asList("hello", "java8", "function", "predicate");
List newList = filterStr(list, s -> s.length() > 5);
for (String s : newList) {
System.out.println(s);
}
}
// Function 彿°åæ¥å£ï¼å¤çå符串
public String strHandler(String str, Function function) {
return function.apply(str);
}
@Test
public void testFunction() {
String str1 = strHandler("æµè¯å
ç½®å½æ°å¼æ¥å£", s -> s.substring(2));
System.out.println(str1);
String str2 = strHandler("abcdefg", s -> s.toUpperCase());
System.out.println(str2);
}
//Supplier ä¾ç»åæ¥å£ :产çæå®ä¸ªæ°çæ´æ°ï¼å¹¶æ¾å
¥éå
public List getNumList(int num, Supplier supplier) {
List list = new ArrayList<>();
for (int i = 0; i < num; i++) {
Integer n = supplier.get();
list.add(n);
}
return list;
}
@Test
public void testSupplier() {
List numList = getNumList(10, () -> (int) (Math.random() * 100));
for (Integer num : numList) {
System.out.println(num);
}
}
//Consumer æ¶è´¹åæ¥å£ :ä¿®æ¹åæ°
public void modifyValue(Integer value, Consumer consumer) {
consumer.accept(value);
}
@Test
public void testConsumer() {
modifyValue(3, s -> System.out.println(s * 3));
}
}
```
**Package java.util.function** å
ä¸è¿æä¾äºå¾å¤å
¶ä»çæ¼åæ¹æ³ã

**?> Tip**
Javaç±»åè¦ä¹æ¯å¼ç¨ç±»åï¼ByteãIntegerãObjuctãListï¼ï¼è¦ä¹æ¯åå§ç±»åï¼intãdoubleãbyteãcharï¼ã使¯æ³ååªè½ç»å®å°å¼ç¨ç±»åãå°åå§ç±»å转æ¢ä¸ºå¯¹åºçå¼ç¨ç±»åï¼å«**è£
ç®±**ï¼ç¸åï¼å°å¼ç¨ç±»å转æ¢ä¸ºå¯¹åºçåå§ç±»åï¼å«**æç®±**ãå½ç¶Javaæä¾äºèªå¨è£
ç®±æºå¶å¸®æä»¬æ§è¡äºè¿ä¸æä½ã
```java
List list = new ArrayList();
for (int i = 0; i < 10; i++) {
list.add(i); //int被è£
箱为Integer
}
```
ä½è¿å¨æ§è½æ¹é¢æ¯è¦ä»åºä»£ä»·çãè£
ç®±åç弿¬è´¨ä¸å°±æ¯æåå§ç±»åå
裹起æ¥ï¼å¹¶ä¿åå¨å éãå æ¤ï¼è£
ç®±åçå¼éè¦æ´å¤çå
åï¼å¹¶éè¦é¢å¤çå
åæç´¢æ¥è·å被å
裹çåå§å¼ã
以ä¸funcitonå
ä¸ç**IntPredicateãDoubleConsumerãLongBinaryOperatorãToDoubleFuncationçå°±æ¯é¿å
èªå¨è£
ç®±çæä½**ãä¸è¬ï¼é对ä¸é¨çè¾å
¥åæ°ç±»åç彿°å¼æ¥å£çåç§°é½è¦å ä¸å¯¹åºçåå§ç±»ååç¼ã
------
## ä¸ãæ¹æ³å¼ç¨
- æ¹æ³å¼ç¨æ¯æéè¿æ¹æ³çå忥æåä¸ä¸ªæ¹æ³
- å½è¦ä¼ éç» Lambda ä½çæä½ï¼å·²ç»æå®ç°çæ¹æ³äºï¼å°±å¯ä»¥ä½¿ç¨æ¹æ³å¼ç¨ï¼å®ç°æ½è±¡æ¹æ³çåæ°å表ï¼å¿
须䏿¹æ³å¼ç¨æ¹æ³çåæ°åè¡¨ä¿æä¸è´ï¼ï¼
- æ¹æ³å¼ç¨çå¯ä¸ç¨éæ¯æ¯æLambdaçç®å(å¯ä»¥çè§£ä¸ºæ¹æ³å¼ç¨æ¯lambda表达å¼çå¦ä¸ç§è¡¨ç°å½¢å¼ï¼å¿«æ·åæ³)
ä½¿ç¨ **::** æä½ç¬¦å°**æ¹æ³å**å**对象æç±»**çåååéå¼
### 1. eg
```java
BinaryOperator binaryOperator = (x,y)->Math.pow(x,y);
//çä»·äº
BinaryOperator binaryOperator1 = Math::pow;
```
### 2. æ¹æ³å¼ç¨ç±»å
Java 8 æä¾äº4ç§æ¹æ³å¼ç¨
| Kind | Example |
| -------------------------------- | -------------------------------------- |
| éææ¹æ³å¼ç¨ | `ContainingClass::staticMethodName` |
| ç¹å®å¯¹è±¡çå®ä¾æ¹æ³å¼ç¨ | `containingObject::instanceMethodName` |
| ç¹å®ç±»åçä»»æå¯¹è±¡çå®ä¾æ¹æ³å¼ç¨ | `ContainingType::methodName` |
| æé å¨å¼ç¨ | `ClassName::new` |
#### 1. éææ¹æ³å¼ç¨
```java
//æ¯è¾å¹´é¾çæ¹æ³å¨Person.compareByAgeçå·²ç»åå¨ï¼æä»¥å¯ä»¥ä½¿ç¨æ¹æ³å¼ç¨
Arrays.sort(rosterAsArray, Person::compareByAge);
//---------------------
@Test
public void test3(){
BiFunction bif = (x,y)->Math.max(x,y);
System.out.println(bif.apply(22.1,23.2));
System.out.println("===çä»·äº===");
BiFunction bif1 = Math::max;
System.out.println(bif1.apply(22.1,23.2));
}
@Test
public void test4(){
Comparator com = (x, y)->Integer.compare(x,y);
System.out.println(com.compare(1,2));
System.out.println("===çä»·äº===");
Comparator com1 = Integer::compare;
System.out.println(com1.compare(1,2));
}
```
#### 2. ç¹å®å¯¹è±¡çå®ä¾æ¹æ³å¼ç¨
```java
class ComparisonProvider {
public int compareByName(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
public int compareByAge(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
}
ComparisonProvider myComparisonProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);
//------------------------
@Test
public void test2() {
Person person = new Person("Tom", IsoChronology.INSTANCE.date(1995, 6, 20), Person.Sex.MALE, "[email protected]");
Supplier sup = () -> person.getName();
System.out.println(sup.get());
System.out.println("===çä»·äº===");
Supplier sup1 = person::getName;
System.out.println(sup1.get());
}
```
#### 3. ç¹å®ç±»åçä»»æå¯¹è±¡çå®ä¾æ¹æ³å¼ç¨
```java
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
//-------------------
@Test
public void test5(){
BiPredicate bp = (x,y)->x.equals(y);
System.out.println(bp.test("Javaæ
æ¥å±","Javaæ
æ¥å±1"));
System.out.println("===çä»·äº===");
BiPredicate bp1 = String::equals;
System.out.println(bp.test("Javaæ
æ¥å±","Javaæ
æ¥å±"));
}
```
#### 4. æé å¨å¼ç¨
å°ä¸ä¸ªéåå
å
ç´ å¤å¶å°å¦ä¸ä¸ªéåä¸ã
```java
public static , DEST extends Collection>
DEST transferElements(
SOURCE sourceCollection,
Supplier collectionFactory) {
DEST result = collectionFactory.get();
for (T t : sourceCollection) {
result.add(t);
}
return result;
}
```
Supplieræ¯ä¸ä¸ªå½æ°å¼æ¥å£ï¼æ¨å¯ä»¥ä½¿ç¨lambda表达å¼è°ç¨æ¹æ³TransferElements
```java
Set rosterSetLambda =
transferElements(roster, () -> { return new HashSet<>(); });
```
ä½¿ç¨æé å¨å¼ç¨ä»£æ¿lambda表达å¼
```java
Set rosterSet = transferElements(roster, HashSet::new);
//Javaç¼è¯å¨å¯ä»¥æ¨æåºè¦å建å
å«Personç±»åå
ç´ çHashSetéåï¼å¯ç®å
Set rosterSet = transferElements(roster, HashSet::new);
```
```java
Function fun = (n) -> new MyClass(n);
//çä»·äº
Function fun = MyClass::new;
// å¸¦ä¸¤ä¸ªåæ°çæé å¨å¼ç¨å°±è¦ç¨BiFunctionï¼å¤ä¸ªåæ°çè¯ï¼è¿å¯ä»¥èªå®ä¹ä¸ä¸ªè¿æ ·ç彿°å¼æ¥å£
```
```java
@Test
public void test6(){
Supplier sup = ()->new Person("Tom", IsoChronology.INSTANCE.date(1995, 6, 20), Person.Sex.MALE, "[email protected]");
System.out.println(sup.get());
```
**æé å¨å¼ç¨è¿å¯ä»¥å建æ°ç»**
```java
@Test
public void test7(){
Function fun = args -> new String[args];
String[] strs = fun.apply(6);
System.out.println(strs.length);
System.out.println("===çä»·äº===");
Function fun1 = String[]::new;
String[] strs1 = fun1.apply(6);
System.out.println(strs1.length);
}
```
------
## åãStreamââ彿°å¼æ°æ®å¤ç

Stream æ¯ Java8 ä¸å¤çéåçå
³é®æ½è±¡æ¦å¿µï¼å®å¯ä»¥æå®ä½ 叿坹éåè¿è¡çæä½ï¼å¯ä»¥æ§è¡éå¸¸å¤æçæ¥æ¾ãè¿æ»¤åæ å°æ°æ®çæä½ã 使ç¨Stream API 对éåæ°æ®è¿è¡æä½ï¼å°±ç±»ä¼¼äºä½¿ç¨ SQL æ§è¡çæ°æ®åºæ¥è¯¢ãä¹å¯ä»¥ä½¿ç¨ Stream API æ¥å¹¶è¡æ§è¡æä½ãç®èè¨ä¹ï¼ **Stream API æä¾äºä¸ç§é«æä¸æäºä½¿ç¨çå¤çæ°æ®çæ¹å¼**ã
### 1. Streamæ¯ä¸ªå¥
Stream(æµ) æ¯æ°æ®æ¸ éï¼ç¨äºæä½æ°æ®æºï¼éåãæ°ç»çï¼æçæçå
ç´ åºåã
â**éåè®²çæ¯æ°æ®ï¼æµè®²çæ¯è®¡ç®ï¼**â
?>**tip**
- Stream èªå·±ä¸ä¼åå¨å
ç´
- Stream ä¸ä¼æ¹åæºå¯¹è±¡ãç¸åï¼ä»ä»¬ä¼è¿åä¸ä¸ªææç»æçæ°Stream
- Stream æä½æ¯å»¶è¿æ§è¡çãè¿æå³çä»ä»¬ä¼çå°éè¦ç»æçæ¶åææ§è¡
æµæä½æä¸¤ä¸ªéè¦ç¹ç¹
- æµæ°´çº¿ââå¾å¤æµæä½æ¬èº«ä¼è¿åä¸ä¸ªæµï¼è¿æ ·å¤ä¸ªæä½å°±å¯ä»¥é¾æ¥èµ·æ¥ï¼å½¢æä¸ä¸ªå¤§çæµæ°´çº¿
- å
é¨è¿ä»£ââä¸è¿ä»£å¨æ¾ç¤ºè¿ä»£éåä¸åï¼æµçè¿ä»£æä½é½å¨èåè¿è¡
### 2. Stream çæä½ä¸ä¸ªæ¥éª¤
1. **å建 Stream** ä¸ä¸ªæ°æ®æºï¼å¦ï¼éåãæ°ç»ï¼ï¼è·åä¸ä¸ªæµ
2. **ä¸é´æä½**(ä¸ä¸ªä¸é´æä½é¾ï¼å¯¹æ°æ®æºçæ°æ®è¿è¡å¤çï¼å½¢æä¸æ¡æµçæµæ°´çº¿)
3. **ç»æ¢æä½**(ä¸ä¸ªç»æ¢æä½ï¼æ§è¡ä¸é´æä½é¾ï¼å¹¶äº§çç»æ)

#### 2.1. å建 Stream
Java8 ä¸ç Collection æ¥å£è¢«æ©å±ï¼æä¾äºä¸¤ä¸ªè·åæµçæ¹æ³ï¼
- default Stream\ **stream()** : è¿åä¸ä¸ªé¡ºåºæµ
- default Stream\ **parallelStream()** : è¿åä¸ä¸ªå¹¶è¡æµ
##### ç±æ°ç»å建æµ
Java8 ä¸ç Arrays çéææ¹æ³ stream() å¯ä»¥è·åæ°ç»æµï¼
- static Stream stream(T[] array): è¿åä¸ä¸ªæµ
**é载形å¼ï¼è½å¤å¤ç对åºåºæ¬ç±»åçæ°ç»ï¼**
- public static IntStream stream(int[] array)
- public static LongStream stream(long[] array)
- public static DoubleStream stream(double[] array)
##### ç±å¼å建æµ
å¯ä»¥ä½¿ç¨éææ¹æ³ Stream.of(), éè¿æ¾ç¤ºå¼å建ä¸ä¸ªæµãå®å¯ä»¥æ¥æ¶ä»»ææ°éçåæ°ã
- public static\ Stream\ of(T... values) : è¿åä¸ä¸ªæµ
##### ç±å½æ°å建æµï¼å建æ éæµ
å¯ä»¥ä½¿ç¨éææ¹æ³ Stream.iterate() å Stream.generate(), å建æ éæµã
- è¿ä»£
- public static\ Stream\ iterate(final T seed, final UnaryOperator\ f)
- çæ
- public static\ Stream\ generate(Supplier\ s) :
```java
//å建 Stream
@Test
public void test1(){
//1. Collection æä¾äºä¸¤ä¸ªæ¹æ³ stream() ä¸ parallelStream()
List list = new ArrayList<>();
Stream stream = list.stream(); //è·åä¸ä¸ªé¡ºåºæµ
Stream parallelStream = list.parallelStream(); //è·åä¸ä¸ªå¹¶è¡æµ
//2. éè¿ Arrays ä¸ç stream() è·åä¸ä¸ªæ°ç»æµ
Integer[] nums = new Integer[10];
Stream stream1 = Arrays.stream(nums);
//3. éè¿ Stream ç±»ä¸éææ¹æ³ of()
Stream stream2 = Stream.of(1,2,3,4,5,6);
//4. å建æ éæµ
//è¿ä»£
Stream stream3 = Stream.iterate(0, (x) -> x + 2).limit(10);
stream3.forEach(System.out::println);
//çæ
Stream stream4 = Stream.generate(Math::random).limit(2);
stream4.forEach(System.out::println);
}
```
#### 2.2. Stream çä¸é´æä½
å¤ä¸ªä¸é´æä½å¯ä»¥è¿æ¥èµ·æ¥å½¢æä¸ä¸ªæµæ°´çº¿ï¼é¤éæµæ°´çº¿ä¸è§¦åç»æ¢æä½ï¼å¦åä¸é´æä½ä¸ä¼æ§è¡ä»»ä½çå¤çï¼ èå¨ç»æ¢æä½æ¶ä¸æ¬¡æ§å
¨é¨å¤çï¼ç§°ä¸ºâæ°æ§æ±å¼âã
##### 2.2.1 çéä¸åç
| æ¹æ³ | æè¿° |
| ------------------- | ------------------------------------------------------------ |
| filter(Predicate p) | æ¥æ¶ Lambda ï¼ ä»æµä¸æé¤æäºå
ç´ |
| distinct() | çéï¼éè¿æµæçæå
ç´ ç hashCode() å equals() å»é¤éå¤å
ç´ |
| limit(long maxSize) | æªææµï¼ä½¿å
¶å
ç´ ä¸è¶
è¿ç»å®æ°é |
| skip(long n) | è·³è¿å
ç´ ï¼è¿åä¸ä¸ªææäºå n 个å
ç´ çæµãè¥æµä¸å
ç´ ä¸è¶³ n 个ï¼åè¿åä¸ä¸ªç©ºæµãä¸ limit(n) äºè¡¥ |
```java
List persons = Person.createRoster();
//å
é¨è¿ä»£ï¼è¿ä»£æä½ Stream API å
é¨å®æ
@Test
public void test2(){
//ææçä¸é´æä½ä¸ä¼åä»»ä½çå¤ç
Stream stream = persons.stream()
.filter((e) -> {
System.out.println("æµè¯ä¸é´æä½");
return e.getAge() <= 35;
});
//åªæå½åç»æ¢æä½æ¶ï¼ææçä¸é´æä½ä¼ä¸æ¬¡æ§çå
¨é¨æ§è¡ï¼ç§°ä¸ºâæ°æ§æ±å¼â
stream.forEach(System.out::println);
}
//å¤é¨è¿ä»£
@Test
public void test3(){
Iterator it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
@Test
public void test4(){
persons.stream()
.filter((p) -> {
System.out.println("大äº25å²çæåï¼"); // && ||
return (p.getAge()) >= 25;
}).limit(3)
.forEach(System.out::println);
}
@Test
public void test5(){
persons.parallelStream()
.filter((e) -> e.getAge() >= 20)
.skip(2)
.forEach(System.out::println);
}
@Test
public void test6(){
persons.stream()
.distinct()
.forEach(System.out::println);
}
```
##### 2.2.2 æ å°
| æ¹æ³ | æè¿° |
| ------------------------------- | ------------------------------------------------------------ |
| map(Function f) | æ¥æ¶ä¸ä¸ªå½æ°ä½ä¸ºåæ°ï¼è¯¥å½æ°ä¼è¢«åºç¨å°æ¯ä¸ªå
ç´ ä¸ï¼å¹¶å°å
¶æ å°æä¸ä¸ªæ°çå
ç´ |
| mapToDouble(ToDoubleFunction f) | æ¥æ¶ä¸ä¸ªå½æ°ä½ä¸ºåæ°ï¼è¯¥å½æ°ä¼è¢«åºç¨å°æ¯ä¸ªå
ç´ ä¸ï¼äº§çä¸ä¸ªæ°ç DoubleStream |
| mapToInt(ToIntFunction f) | æ¥æ¶ä¸ä¸ªå½æ°ä½ä¸ºåæ°ï¼è¯¥å½æ°ä¼è¢«åºç¨å°æ¯ä¸ªå
ç´ ä¸ï¼äº§çä¸ä¸ªæ°ç IntStreamã |
| mapToLong(ToLongFunction f) | æ¥æ¶ä¸ä¸ªå½æ°ä½ä¸ºåæ°ï¼è¯¥å½æ°ä¼è¢«åºç¨å°æ¯ä¸ªå
ç´ ä¸ï¼äº§çä¸ä¸ªæ°ç LongStream |
| flatMap(Function f) | æ¥æ¶ä¸ä¸ªå½æ°ä½ä¸ºåæ°ï¼å°æµä¸çæ¯ä¸ªå¼é½æ¢æå¦ä¸ä¸ªæµï¼ç¶åææææµè¿æ¥æä¸ä¸ªæµ |
```java
//æ å°
@Test
public void test1(){
Stream str = persons.stream()
.map((e) -> e.getName());
System.out.println("-------------------------------------------");
List strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
Stream stream = strList.stream()
.map(String::toUpperCase);
stream.forEach(System.out::println);
System.out.println("---------------------------------------------");
Stream stream3 = strList.stream()
.flatMap(TestStreamAPI::filterCharacter);
stream3.forEach(System.out::println);
}
public static Stream filterCharacter(String str){
List list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
```
##### 2.2.3 æåº
| æ¹æ³ | æè¿° |
| ----------------------- | ---------------------------------- |
| sorted() | 产çä¸ä¸ªæ°æµï¼å
¶ä¸æèªç¶é¡ºåºæåº |
| sorted(Comparator comp) | 产çä¸ä¸ªæ°æµï¼å
¶ä¸ææ¯è¾å¨é¡ºåºæåº |
```java
@Test
public void test(){
persons.stream()
.map(Person::getName)
.sorted()
.forEach(System.out::println);
System.out.println("------------------------------------");
persons.stream()
.sorted((x, y) -> {
if(x.getAge() == y.getAge()){
return x.getName().compareTo(y.getName());
}else{
return Integer.compare(x.getAge(), y.getAge());
}
}).forEach(System.out::println);
}
```
#### 2.3. Stream çç»æ¢æä½
ç»ç«¯æä½ä¼ä»æµçæµæ°´çº¿çæç»æãå
¶ç»æå¯ä»¥æ¯ä»»ä½ä¸æ¯æµçå¼ï¼ä¾å¦ï¼ListãIntegerï¼çè³æ¯ void
##### 2.3.1 æ¥æ¾ä¸å¹é
| æ¹æ³ | æè¿° |
| ---------------------- | ------------------------------------------------------------ |
| allMatch(Predicate p) | æ£æ¥æ¯å¦å¹é
ææå
ç´ |
| anyMatch(Predicate p) | æ£æ¥æ¯å¦è³å°å¹é
ä¸ä¸ªå
ç´ |
| noneMatch(Predicate p) | æ£æ¥æ¯å¦æ²¡æå¹é
ææå
ç´ |
| findFirst() | è¿å第ä¸ä¸ªå
ç´ |
| findAny() | è¿åå½åæµä¸çä»»æå
ç´ |
| count() | è¿åæµä¸å
ç´ æ»æ° |
| max(Comparator c) | è¿åæµä¸æå¤§å¼ |
| min(Comparator c) | è¿åæµä¸æå°å¼ |
| forEach(Consumer c) | **å
é¨è¿ä»£(ä½¿ç¨ Collection æ¥å£éè¦ç¨æ·å»åè¿ ä»£ï¼ç§°ä¸ºå¤é¨è¿ä»£ãç¸åï¼Stream API 使ç¨å
é¨ è¿ä»£ââå®å¸®ä½ æè¿ä»£åäº)** |
```java
public class TestStreamAPI2 {
List persons = Person.createRoster();
//3. ç»æ¢æä½
@Test
public void test1(){
boolean bl = persons.stream()
.allMatch((e) -> e.getGender().equals(Person.Sex.FEMALE));
System.out.println("æææåé½ä¸ºå¥³æ§åï¼"+bl);
boolean bl1 = persons.stream()
.anyMatch((e) -> e.getGender().equals(Person.Sex.FEMALE));
System.out.println("æå䏿女æ§åï¼"+bl1);
boolean bl2 = persons.stream()
.noneMatch((e) -> e.getGender().equals(Person.Sex.FEMALE));
System.out.println("æå䏿¯ä¸æ¯æ²¡æå¥³æ§ï¼"+bl2);
}
@Test
public void test2(){
Optional op = persons.stream()
.sorted(Comparator.comparingInt(Person::getAge))
.findFirst();
System.out.println("年龿å°çï¼"+op.get());
Optional op2 = persons.parallelStream()
.filter((e) -> e.getGender().equals(Person.Sex.MALE))
.findAny();
System.out.println("é便æ¾ä¸ªç·çï¼"+op2.get());
}
@Test
public void test3(){
long count = persons.stream()
.filter((e) -> e.getGender().equals(Person.Sex.FEMALE))
.count();
System.out.println("女çç人æ°ï¼"+count);
Optional op = persons.stream()
.map(Person::getAge)
.max(Integer::compare);
System.out.println("æå¤§å¹´é¾ï¼"+op.get());
Optional op2 = persons.stream()
.min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
System.out.println("æå°å¹´é¾æåï¼"+op2.get());
}
//注æï¼æµè¿è¡äºç»æ¢æä½åï¼ä¸è½å次使ç¨
@Test
public void test4(){
Stream stream = persons.stream()
.filter((e) -> e.getGender().equals(Person.Sex.FEMALE));
long count = stream.count();
stream.map(Person::getAge)
.max(Integer::compare);
}
}
```
##### 2.3.2 è§çº¦
| æ¹æ³ | æè¿° |
| -------------------------------- | ---------------------------------------------------------- |
| reduce(T iden, BinaryOperator b) | å¯ä»¥å°æµä¸å
ç´ åå¤ç»åèµ·æ¥ï¼å¾å°ä¸ä¸ªå¼ã è¿å T |
| reduce(BinaryOperator b) | å¯ä»¥å°æµä¸å
ç´ åå¤ç»åèµ·æ¥ï¼å¾å°ä¸ä¸ªå¼ã è¿å Optional\ |
夿³¨ï¼map å reduce çè¿æ¥é常称为 map-reduce 模å¼ï¼å Google ç¨å®æ¥è¿è¡ç½ç»æç´¢èåºåã
```java
List persons = Person.createRoster();
//3. ç»æ¢æä½:å½çº¦
@Test
public void test1(){
List list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream()
.reduce(0, (x, y) -> x + y);
System.out.println(sum);
System.out.println("----------------------------------------");
Optional op = persons.stream()
.map(Person::getAge)
.reduce(Integer::sum);
System.out.println("æææåçå¹´é¾åï¼"+op.get());
}
//éæ±ï¼æç´¢ååä¸ âBâ åºç°ç次æ°
@Test
public void test2(){
Optional sum = persons.stream()
.map(Person::getName)
.flatMap(TestStreamAPI1::filterCharacter)
.map((ch) -> {
if(ch.equals('B'))
return 1;
else
return 0;
}).reduce(Integer::sum);
System.out.println(sum.get());
}
```
##### 2.3.3 æ¶é
| æ¹æ³ | æè¿° |
| -------------------- | ------------------------------------------------------------ |
| collect(Collector c) | å°æµè½¬æ¢ä¸ºå
¶ä»å½¢å¼ãæ¥æ¶ä¸ä¸ª Collectoræ¥å£ç å®ç°ï¼ç¨äºç»Streamä¸å
ç´ åæ±æ»çæ¹æ³ |
#### Collectors
Collectoræ¥å£ä¸æ¹æ³çå®ç°å³å®äºå¦ä½å¯¹æµæ§è¡æ¶éæä½(妿¶éå° ListãSetãMap)ã使¯ **Collectors** å®ç¨ç±»æä¾äºå¾å¤éææ¹æ³ï¼å¯ä»¥æ¹ä¾¿å°åå»ºå¸¸è§æ¶éå¨å®ä¾ï¼å
·ä½æ¹æ³ä¸å®ä¾å¦ä¸è¡¨ï¼ https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
| æ¹æ³ | è¿åç±»å | ä½ç¨ | ç¤ºä¾ |
| ----------------- | --------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| toList | List\ | ææµä¸å
ç´ æ¶éå°List | List list= list.stream().collect(Collectors.toList()); |
| toSet | Set\ | ææµä¸å
ç´ æ¶éå°Set | Set set= list.stream().collect(Collectors.toSet()); |
| toCollection | Collection\ | ææµä¸å
ç´ æ¶éå°å建çéå | Collectione mps=list.stream().collect(Collectors.toCollection(ArrayList::new)); |
| counting | Long | è®¡ç®æµä¸å
ç´ çä¸ªæ° | long count = list.stream().collect(Collectors.counting()); |
| summingInt | Integer | 对æµä¸å
ç´ çæ´æ°å±æ§æ±å | Integer sum = persons.stream() .collect(Collectors.summingInt(Person::getAge)); |
| averagingInt | Double | è®¡ç®æµä¸å
ç´ Integer屿§çå¹³åå¼ | double avg= list.stream().collect(Collectors.averagingInt(Person::getAge)); |
| summarizingInt | IntSummaryStatistics | æ¶éæµä¸Integer屿§çç»è®¡å¼ã å¦ï¼å¹³åå¼ | IntSummaryStatistics iss= list.stream().collect(Collectors.summarizingInt(Person::getAge)); |
| joining | String | è¿æ¥æµä¸æ¯ä¸ªå符串 | String str= list.stream().map(Person::getName).collect(Collectors.joining()); |
| maxBy | Optional\ | æ ¹æ®æ¯è¾å¨éæ©æå¤§å¼ | Optionalmax= list.stream().collect(Collectors.maxBy(comparingInt(Person::getAge))); |
| minBy | Optonal\ | æ ¹æ®æ¯è¾å¨éæ©æå°å¼ | Optional min = list.stream().collect(Collectors.minBy(comparingInt(Person::getAge))); |
| reducing | å½çº¦äº§ççç±»å | ä»ä¸ä¸ªä½ä¸ºç´¯å å¨çåå§å¼å¼å§ï¼å©ç¨BinaryOperatorä¸ æµä¸å
ç´ é个ç»åï¼ä»èå½ çº¦æåä¸ªå¼ | int total=list.stream().collect(Collectors.reducing(0, Person::getAge, Integer::sum)); |
| collectingAndThen | 转æ¢å½æ°è¿åçç±»å | å
裹å¦ä¸ä¸ªæ¶éå¨ï¼å¯¹å
¶ç»æè½¬æ¢å½æ° | int how= list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size)); |
| groupingBy | Map> | æ ¹æ®æå±æ§å¼å¯¹æµåç»ï¼å±æ§ä¸ºKï¼ç»æä¸ºV | Map> map = persons.stream() .collect(Collectors.groupingBy(Person::getGender)); |
| partitioningBy | Map> | æ ¹æ®trueæfalseè¿è¡ååº | Map> map = persons.stream() .collect(Collectors.partitioningBy((e) -> e.getAge() >= 50)); |
```java
@Test
public void test3(){
List list = persons.stream()
.map(Person::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
}
@Test
public void test4(){
Optional max = persons.stream()
.map(Person::getAge)
.collect(Collectors.maxBy(Integer::compare));
System.out.println("æå¤§å¹´é¾ï¼"+max.get());
Optional op = persons.stream().min(Comparator.comparingInt(Person::getAge));
System.out.println("æå°å¹´é¾çæåï¼"+op.get());
Integer sum = persons.stream()
.collect(Collectors.summingInt(Person::getAge));
System.out.println("æææåå¹´é¾åï¼"+sum);
IntSummaryStatistics dss = persons.stream()
.collect(Collectors.summarizingInt(Person::getAge));
System.out.println("æå¤§å¹´é¾ï¼"+dss.getMax());
}
//åç»
@Test
public void test5(){
Map> map = persons.stream()
.collect(Collectors.groupingBy(Person::getGender));
System.out.println("ææ§å«åç»ï¼"+map);
}
//å¤çº§åç»
@Test
public void test6(){
Map>> map = persons.stream()
.collect(Collectors.groupingBy(Person::getGender, Collectors.groupingBy((e) -> {
if(e.getAge() >= 60)
return "èå¹´";
else if(e.getAge() >= 35)
return "ä¸å¹´";
else
return "æå¹´";
})));
System.out.println(map);
}
//ååº
@Test
public void test7(){
Map> map = persons.stream()
.collect(Collectors.partitioningBy((e) -> e.getAge() >= 50));
System.out.println(map);
}
@Test
public void test8(){
String str = persons.stream()
.map(Person::getName)
.collect(Collectors.joining("," , "----", "----"));
System.out.println(str);
}
@Test
public void test9(){
Optional sum = persons.stream()
.map(Person::getAge)
.collect(Collectors.reducing(Integer::sum));
System.out.println(sum.get());
}
```
### 3. å¹¶è¡æµä¸ä¸²è¡æµ
#### å
说说并è¡åå¹¶å
å¹¶åæ¯ä¸¤ä¸ªä»»å¡å
±äº«æ¶é´æ®µï¼å¹¶è¡åæ¯ä¸¤ä¸ªä»»å¡å¨å䏿¶é´åçï¼æ¯å¦è¿è¡å¨å¤æ ¸CPUä¸ã

**å¹¶è¡æµå°±æ¯æä¸ä¸ªå
容åæå¤ä¸ªæ°æ®åï¼å¹¶ç¨ä¸åç线ç¨åå«å¤çæ¯ä¸ªæ°æ®åçæµ**ã
Java 8 ä¸å°å¹¶è¡è¿è¡äºä¼åï¼æä»¬å¯ä»¥å¾å®¹æçå¯¹æ°æ®è¿è¡å¹¶è¡æä½ãStream API å¯ä»¥å£°ææ§å°éè¿ `parallel()` ä¸ `sequential()` å¨å¹¶è¡æµä¸é¡ºåºæµä¹é´è¿è¡åæ¢ã妿æ³ä»ä¸ä¸ªéåç±»å建ä¸ä¸ªæµï¼è°ç¨`parallerStream`å°±å¯ä»¥è·åä¸ä¸ªå¹¶è¡æµã
```java
public static long parallelSum(long n) {
return Stream.iterate(1L, i -> i + 1)
.limit(n)
.parallel() //å°æµè½¬åä¸ºå¹¶è¡æµ
.reduce(0L, Long::sum);
}
```
#### é
ç½®å¹¶è¡æµä½¿ç¨ççº¿ç¨æ±
ä½¿ç¨æµçparallelæ¹æ³ï¼ä½ å¯è½ä¼æ³å°ï¼å¹¶è¡æµç¨ççº¿ç¨æ¯ä»åªå¿æ¥çï¼æå¤å°ä¸ªï¼æä¹èªå®ä¹ï¼
å¹¶è¡æµå
é¨ä½¿ç¨äºé»è®¤ç**ForkJoinPool**(忝/åå¹¶æ¡æ¶)ï¼å®é»è®¤ççº¿ç¨æ°éå°±æ¯ä½ çå¤ç卿°éï¼è¿ä¸ªå¼æ¯ç±`Runtime.getrRuntime().acailable-Processors()`å¾å°ã
ä½ å¯ä»¥éè¿ç³»ç»å±æ§`java.util.concurrent.ForkJoinPool.common.parallelism`æ¥æ¹åçº¿ç¨æ± 大å°ï¼å¦ä¸
`System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","12");`ï¼è¿æ¯ä¸ä¸ªå
¨å±è®¾ç½®ï¼å æ¤ä¼å½±å代ç 䏿æçå¹¶è¡æµï¼ç®åè¿æ æ³ä¸é¨ä¸ºæä¸ªå¹¶è¡æµæå®è¯¥å¼ï¼ä¸è¬èè¨ï¼è®©ForkJoinPoolç大å°çäºå¤ç卿°éæ¯ä¸ªä¸éçé»è®¤å¼ï¼ã
#### é«æä½¿ç¨å¹¶è¡æµ
- å¹¶è¡æµå¹¶ä¸æ¯æ»æ¯æ¯é¡ºåºæµå¿«
- çæè£
ç®±ãèªå¨è£
ç®±åæç®±æä½ä¼å¤§å¤§é使§è½ï¼Java8 䏿åå§ç±»åæµï¼IntStreamãLongStream...ï¼æ¥é¿å
è¿ç§æä½
- æäºæä½æ¬èº«å¨å¹¶è¡æµä¸çæ§è½å°±æ¯é¡ºåºæµå·®ï¼ç¹å«æ¯ limit å findFirst çä¾èµå
ç´ é¡ºåºçæä½ï¼ä»ä»¬å¨å¹¶è¡æµä¸æ§è¡ç代价就é常大
- è¿è¦èèæµçæä½æµæ°´çº¿çæ»è®¡ç®ææ¬
- 对äºè¾å°çæ°æ®éï¼æ²¡å¿
è¦ä½¿ç¨å¹¶è¡æµ
- è¦èèæµèåçæ°æ®ç»ææ¯å¦æäºåè§£ï¼æ¯å¦ï¼ArrayList çæåæçæ¯ LinkedList é«å¾å¤ï¼åè
æ ééå
- è¿è¦èèç»ç«¯æä½ä¸åå¹¶æ¥éª¤ç代价æ¯å¤§æ¯å°ï¼æ¯å¦Collectorä¸çcombineræ¹æ³ï¼
### 4. Fork/Join æ¡æ¶
å¹¶è¡æµèå使ç¨çåºç¡æ¡æ¶å°±æ¯ Java7 ä¸å¼å
¥ç**忝/åå¹¶æ¡æ¶**ã
Fork/Joinï¼åæ¯/åå¹¶ï¼æ¡æ¶çç®çæ¯ä»¥é彿¹å¼å°å¯ä»¥å¹¶è¡ç任塿å(fork)ææ´å°çä»»å¡ï¼ç¶åå°æ¯ä¸ªä»»å¡çç»æåå¹¶ (join)èµ·æ¥çææ´ä½ææã宿¯ExectorServiceæ¥å£çä¸ä¸ªå®ç°ï¼æåä»»å¡åé
ç»çº¿ç¨æ± ï¼ç§°ä¸ºForkJoinPoolï¼ä¸çå·¥ä½çº¿ç¨ã
Fork/Join æ¡æ¶ï¼å°±æ¯å¨å¿
è¦çæ
åµä¸ï¼å°ä¸ä¸ªå¤§ä»»å¡ï¼è¿è¡æå(fork)æè¥å¹²ä¸ªå°ä»»å¡ï¼æå°ä¸å¯åææ¶ï¼ï¼åå°ä¸ä¸ªä¸ªçå°ä»»å¡è¿ç®çç»æè¿è¡ join æ±æ»

```java
// ç¨åæ¯/åå¹¶æ¡æ¶ å¹¶è¡æ±å
public class ForkJoinSumCalculator extends RecursiveTask {
private final long[] numbers;
private final int start;
private final int end;
//ä¸åå°ä»»å¡å解为åä»»å¡çæ°ç»å¤§å°
public static long THRESHOLD = 100;
//å
Œ
±æé å¨ç¨äºå建主任å¡
public ForkJoinSumCalculator(long[] numbers) {
this(numbers, 0, numbers.length);
}
//ç§ææé å¨ç¨äºä»¥é彿¹å¼ä¸ºä¸»ä»»å¡å建åä»»å¡
private ForkJoinSumCalculator(long[] numbers, int start, int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
int length = end - start;
//妿大å°å°äºçäºéå¼ï¼é¡ºåºè®¡ç®ç»æ
if (length <= THRESHOLD) {
return computerSequntially();
}
ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length / 2);
leftTask.fork();
ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length / 2, end);
Long rightResult = rightTask.compute(); //忥æ§è¡ç¬¬äºä¸ªä»»å¡ï¼
Long leftResult = leftTask.join(); // 读å第ä¸ä¸ªåä»»å¡çç»æï¼å¦æå°æªå®æå°±çå¾
return rightResult + leftResult;
}
// åä»»å¡ä¸åå¯åæ¶è®¡ç®å
private long computerSequntially() {
long sum = 0;
for (int i = start; i < end; i++) {
sum += numbers[i];
}
return sum;
}
public static long forkJoimSum(long n) {
long[] numbers = LongStream.rangeClosed(1, n).toArray();
ForkJoinTask task = new ForkJoinSumCalculator(numbers);
return new ForkJoinPool().invoke(task);
}
public static void main(String[] args) {
System.out.println("sum:" + forkJoimSum(10000));
}
}
```
#### Fork/Join æ¡æ¶ä¸ä¼ ç»çº¿ç¨æ± çåºå«
éç¨ âå·¥ä½çªåâæ¨¡å¼ï¼work-stealingï¼ï¼ 彿§è¡æ°ç任塿¶å®å¯ä»¥å°å
¶æåææ´å°ç任塿§è¡ï¼å¹¶å°å°ä»»å¡å å°çº¿ç¨éåä¸ï¼ç¶ååä»ä¸ä¸ªéæºçº¿ç¨çéåä¸å·ä¸ä¸ªå¹¶æå®æ¾å¨èªå·±çéåä¸ã
ç¸å¯¹äºä¸è¬ççº¿ç¨æ± å®ç°ï¼fork/joinæ¡æ¶çä¼å¿ä½ç°å¨å¯¹å
¶ä¸å
å«çä»»å¡çå¤çæ¹å¼ä¸ï¼å¨ä¸è¬ççº¿ç¨æ± ä¸ï¼å¦æä¸ä¸ªçº¿ç¨æ£å¨æ§è¡çä»»å¡ç±äºæäºåå æ æ³ç»§ç»è¿è¡ï¼é£ä¹è¯¥çº¿ç¨ä¼å¤äºçå¾
ç¶æï¼èå¨fork/joinæ¡æ¶å®ç°ä¸ï¼å¦ææä¸ªåé®é¢ç±äºçå¾
å¦å¤ä¸ä¸ªåé®é¢çå®æèæ æ³ç»§ç»è¿è¡ï¼é£ä¹å¤ç该åé®é¢ç线ç¨ä¼ä¸»å¨å¯»æ¾å
¶ä»å°æªè¿è¡çåé®é¢æ¥æ§è¡ï¼è¿ç§æ¹å¼åå°äºçº¿ç¨ççå¾
æ¶é´ï¼æé«äºæ§è½ã
#### 使ç¨Fork/Joinæ¡æ¶çæä½³åæ³
- 对ä¸ä¸ªä»»å¡è°ç¨joinæ¹æ³ä¼é»å¡è°ç¨æ¹ï¼ç´å°è¯¥ä»»å¡ä½åºç»æãå æ¤ï¼æå¿
è¦å¨ä¸¤ä¸ªåä»»å¡ç计ç®é½å¼å§ä¹ååè°ç¨å®
- ä¸åºè¯¥å¨ RecursiveTask å
é¨ä½¿ç¨ ForkJoinPool ç invoke æ¹æ³ãç¸åï¼ä½ åºè¯¥å§ç»ç´æ¥è°ç¨ compute æfork æ¹æ³ï¼åªæé¡ºåºä»£ç æåºè¯¥ç¨ invoke æ¥å¯å¨å¹¶è¡è®¡ç®
#### å·¥ä½çªå

### 5. Spliterator
âå¯åè¿ä»£å¨âââspliteratorï¼åIterator䏿 ·ï¼ä¹ç¨äºéåæ°æ®æºä¸çå
ç´ ï¼å®æ¯ä¸ºäºå¹¶è¡æ§è¡è设计ã
Java8 为éåæ¡æ¶ä¸å
å«çæææ°æ®ç»æé½æä¾äºä¸ä¸ªé»è®¤ç Spliterator æ¹æ³ãéåå®ç°äºSpliteratoræ¥å£ï¼æ¥å£æä¾äºä¸ä¸ªSpliteratoræ¹æ³ã

## äºãæ¥å£ä¸çé»è®¤æ¹æ³ä¸éææ¹æ³
ä¼ ç»ä¸ï¼Javaä¸å®ç°æ¥å£çç±»å¿
须为æ¥å£ä¸å®ä¹çæ¯ä¸ªæ¹æ³æä¾ä¸ä¸ªå®ç°ç±»ï¼æè
ä»ç¶ç±»ä¸ç»§æ¿å®çå®ç°ãä½å¦æç±»åºç设计è
éè¦ä¿®æ¹æ¥å£ï¼å å
¥æ°çæ¹æ³ï¼è¿ç§æ¹å¼å°±ä¼åºç°é®é¢ãææä½¿ç¨è¯¥æ¥å£çå®ä½ç±»ä¸ºäºéé
æ°çæ¥å£çº¦å®é½éè¦è¿è¡ä¿®æ¹ï¼è¦æ¯è¿ä¹ä¸å
¼å®¹çè¯ï¼è¿æ©è¢«æ·æ±°ï¼ãæä»¥ï¼Java8为äºè§£å³è¿ä¸é®é¢å¼å
¥äºä¸ç§æ°çæºå¶ã**Java8ä¸çæ¥å£æ¯æå¨å£°ææ¹æ³çåæ¶æä¾å®ç°**ãå
¶ä¸ï¼**Java8å
è®¸å¨æ¥å£ä¸å£°æéææ¹æ³**ãå
¶äºï¼Java8å¼å
¥çæ°åè½ââ**é»è®¤æ¹æ³ï¼éè¿é»è®¤æ¹æ³å¯ä»¥æå®æ¥å£æ¹æ³çé»è®¤å®ç°**ï¼å æ¤ï¼å®ç°æ¥å£çç±»å¦æä¸æ¾å¼çæä¾è¯¥æ¹æ³çå
·ä½å®ç°ï¼å°±ä¼èªå¨ç»§æ¿é»è®¤çå®ç°ï¼è¿ç§æºå¶å¯ä»¥ä½¿ä½ å¹³æ»çè¿è¡æ¥å£çä¼ååå级ï¼ã
#### é»è®¤æ¹æ³
Java 8ä¸å
许æ¥å£ä¸å
å«å
·æå
·ä½å®ç°çæ¹æ³ï¼è¯¥æ¹æ³ç§°ä¸º âé»è®¤æ¹æ³âï¼é»è®¤æ¹æ³ä½¿ç¨ **default** å
³é®å修饰ã
```java
interface MyFunc{
T func(int a);
default String getName(){
return "hello java8";
}
}
```
```java
@Test
public void test1(){
List list = Arrays.asList(22,11,33,55,4);
//sortæ¯Listæ¥å£ä¸çé»è®¤æ¹æ³,naturalOrderæ¯Comparatorçéææ¹æ³
list.sort(Comparator.naturalOrder());
for (Integer integer : list) {
System.out.println(integer);
}
}
```

#### é»è®¤æ¹æ³çâç±»ä¼å
âåå
è¥ä¸ä¸ªæ¥å£ä¸å®ä¹äºä¸ä¸ªé»è®¤æ¹æ³ï¼èå¦å¤ä¸ä¸ªç¶ç±»ææ¥å£ä¸åå®ä¹äºä¸ä¸ªååçæ¹æ³æ¶
- éæ©ç¶ç±»ä¸çæ¹æ³ã妿ä¸ä¸ªç¶ç±»æä¾äºå
·ä½çå®ç°ï¼é£ä¹æ¥å£ä¸å
·æç¸ååç§°ååæ°çé»è®¤æ¹æ³ä¼è¢«å¿½ç¥ã
- æ¥å£å²çªã妿ä¸ä¸ªç¶æ¥å£æä¾ä¸ä¸ªé»è®¤æ¹æ³ï¼èå¦ä¸ä¸ªæ¥å£ä¹æä¾äºä¸ä¸ªå
·æç¸ååç§°ååæ°åè¡¨çæ¹æ³ï¼ä¸ç®¡æ¹æ³æ¯å¦æ¯é»è®¤æ¹æ³ï¼ï¼é£ä¹å¿
é¡»è¦çè¯¥æ¹æ³æ¥è§£å³å²çª
```java
interface MyFunc {
default String getName() {
return "hello java8";
}
}
interface MyFunc1 {
default String getName() {
return "hello Javaæ
æ¥å±";
}
}
class MyClass implements MyFunc, MyFunc1 {
@Override
public String getName() {
return MyFunc1.super.getName();
}
}
```
JavaAPIç设计è
们å
åå©ç¨äºé»è®¤æ¹æ³ï¼ä¸ºé忥å£åç±»æ°å¢äºå¾å¤æ°çæ¹æ³ã

------
## å
ãOptional ç±»
### 1. ç¨ Optional å代 null
*å½ä½ 碰å°ç¨åºä¸æä¸ä¸ªNullPointerExceptionæ¶ç第ä¸å²å¨æ¯ä¸å°±æ¯èµ¶ç´§æ¾å°ä»£ç ï¼æ·»å ä¸ä¸ªifè¯å¥ï¼æ£æ¥ä¸ï¼ï¼*
NullPointerExceptionæ¯Javaç¨åºå¼åä¸å
¸åçå¼å¸¸ã为äºé¿å
è¿ç§å¼å¸¸ï¼æä»¬çä»£ç æå¯è½å
æ¥çä¸å±åä¸å±ç深度åµå¥çnullæ£æ¥ï¼ä»£ç å¯è¯»æ§æå·®ã
Optionalç±»(java.util.Optional) æ¯ä¸ä¸ªå®¹å¨ç±»ï¼ä»£è¡¨ä¸ä¸ªå¼å卿ä¸åå¨ï¼ åæ¥ç¨ null 表示ä¸ä¸ªå¼ä¸åå¨ï¼ç°å¨ Optional å¯ä»¥æ´å¥½ç表达è¿ä¸ªæ¦å¿µãå¹¶ä¸å¯ä»¥é¿å
空æéå¼å¸¸ã
åéå卿¶ï¼Optionalç±»ç¥è¯å¯¹ç±»ç®åå°è£
ãåéä¸å卿¶ï¼ç¼ºå¤±çå¼å°±ä¼è¢«å»ºæ¨¡æä¸ä¸ªâ空âçOptional对象ï¼ç±æ¹æ³`Optional.empty()`è¿åã
å¸¸ç¨æ¹æ³ï¼
- Optional.of(T t) : å建ä¸ä¸ª Optional å®ä¾
- Optional.empty() : å建ä¸ä¸ªç©ºç Optional å®ä¾
- Optional.ofNullable(T t):è¥ t ä¸ä¸º null,å建 Optional å®ä¾,å¦åå建空å®ä¾
- isPresent() : 夿æ¯å¦å
å«å¼ orElse(T t) : 妿è°ç¨å¯¹è±¡å
å«å¼ï¼è¿å该å¼ï¼å¦åè¿åt
- orElseGet(Supplier s) :妿è°ç¨å¯¹è±¡å
å«å¼ï¼è¿å该å¼ï¼å¦åè¿å s è·åçå¼
- map(Function f): 妿æå¼å¯¹å
¶å¤çï¼å¹¶è¿åå¤çåçOptionalï¼å¦åè¿å Optional.empty()
- flatMap(Function mapper):ä¸ map 类似ï¼è¦æ±è¿åå¼å¿
é¡»æ¯Optional
### 2. Optional å®ä¾
#### 2.1 å建Optional对象
```java
@Test
public void test(){
Optional optional = Optional.empty(); //å建ä¸ä¸ªç©ºOptional
Optional op = Optional.of(new Person());
Person p = op.get();
System.out.println(p); //Person{name='null', birthday=null, gender=null, emailAddress='null'}
Person person = null;
Optional op1 = Optional.of(person); //person为nullï¼æåºNullPointerException
Optional op2 = Optional.ofNullable(person); //å建å
许nullå¼å¾Optional对象
}
```
#### 2.2 optional 对象æä½
```java
@Test
public void test4(){
Person person = new Person("Tom",IsoChronology.INSTANCE.date(1999, 7, 15),Person.Sex.FEMALE, "[email protected]")
Optional op = Optional.ofNullable(person);
Optional op1 = op.map(Person::getName);
System.out.println(op1.get());
/**
* ä½¿ç¨ map ä» optional å¯¹è±¡ä¸æåå转æ¢å¼
* å¦ææ³æå人åå§åï¼ä¹åéè¦å¤æpersion !=null,Optionalæä¾äºä¸ä¸ªmapæ¹æ³ï¼å¯¹å
¶å¤ç
**/
Optional op2 = op.map(Person::getName);
System.out.println(op2.get());
//ä½¿ç¨ flatMap 龿¥ optional 对象
Optional op3 = op.flatMap((e) -> Optional.of(e.getName()));
System.out.println(op3.get());
//TODO
}
```
## ä¸ãCompletableFuture ââ ç»åå¼å¼æ¥ç¼ç¨
### 1. Futureæ¥å£
Futureæ¥å£å¨ Java 5 ä¸è¢«å¼å
¥ï¼è®¾è®¡åè¡·æ¯å¯¹å°æ¥æä¸ªæ¶å»ä¼åççç»æè¿è¡å»ºæ¨¡ãå®å»ºæ¨¡äºä¸ç§å¼æ¥è®¡ç®ï¼è¿åä¸ä¸ªæ§è¡è¿ç®ç»æçå¼ç¨ï¼å½è¿ç®ç»æåï¼è¿ä¸ªå¼ç¨è¢«è¿åç»è°ç¨æ¹ãå¨ Futureä¸è§¦åé£äºæ½å¨èæ¶çæä½æè°ç¨çº¿ç¨è§£æ¾åºæ¥ï¼è®©å®è½ç»§ç»æ§è¡å
¶ä»æä»·å¼çå·¥ä½ï¼ ä¸åéè¦çå¾
èæ¶çæä½å®æãæä¸ªæ¯æ¹ï¼ä½ å¯ä»¥æå®æ³è±¡æè¿æ ·çåºæ¯ï¼ä½ æ¿äºä¸è¢è¡£æå°ä½ 䏿çå¹²æ´åºå»æ´è¡£æãå¹²æ´åºåå·¥ä¼ç»ä½ å¼ å票ï¼åè¯ä½ ä»ä¹æ¶åä½ çè¡£æä¼æ´å¥½ï¼è¿å°± æ¯ä¸ä¸ªFutureäºä»¶ï¼ãè¡£æå¹²æ´çåæ¶ï¼ä½ å¯ä»¥å»åå
¶ä»çäºæ
ãFutureçå¦ä¸ä¸ªä¼ç¹æ¯å®æ¯ æ´åºå±çThreadæ´æç¨ãè¦ä½¿ç¨Futureï¼éå¸¸ä½ åªéè¦å°èæ¶çæä½å°è£
å¨ä¸ä¸ªCallable对象ä¸ï¼åå°å®æäº¤ç»ExecutorServiceï¼å°±å¯ä»¥äºãä¸é¢è¿æ®µä»£ç å±ç¤ºäºJava 8ä¹åä½¿ç¨ Futureçä¸ä¸ªä¾åã
```java
ExecutorService executor = Executors.newCachedThreadPool();
Future future = executor.submit(new Callable() {
public Double call() {
return doSomeThings(); //弿¥æ¹å¼å¨æ°ç线ç¨ä¸æ§è¡æä½
}
});
//doSomethingElse(); //弿¥æä½è¿è¡çåæ¶ï¼å¯ä»¥åå
¶ä»äºæ
try {
//è·å弿¥æä½çç»æï¼å¦æé»å¡ï¼ç1ç§åéåº
Double result = future.get(1, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException e) {
}
```
#### 1.1 Futureæ¥å£çå±éæ§
è½ç¶Future以åç¸å
³ä½¿ç¨æ¹æ³æä¾äºå¼æ¥æ§è¡ä»»å¡çè½åï¼ä½æ¯å¯¹äºç»æçè·åå´æ¯å¾ä¸æ¹ä¾¿ï¼åªè½éè¿é»å¡æè
è½®è¯¢çæ¹å¼å¾å°ä»»å¡çç»æãé»å¡çæ¹å¼æ¾ç¶åæä»¬ç弿¥ç¼ç¨çåè¡·ç¸è¿èï¼è½®è¯¢çæ¹å¼åä¼èè´¹æ è°çCPUèµæºï¼èä¸ä¹ä¸è½åæ¶å°å¾å°è®¡ç®ç»æï¼ä¸ºä»ä¹ä¸è½ç¨è§å¯è
设计模å¼å½è®¡ç®ç»æå®æåæ¶éç¥çå¬è
å¢ï¼
Javaçä¸äºæ¡æ¶ï¼æ¯å¦Nettyï¼èªå·±æ©å±äºJavaç `Future`æ¥å£ï¼æä¾äº`addListener`çå¤ä¸ªæ©å±æ¹æ³ãGoogle guava乿ä¾äºéç¨çæ©å±Future:ListenableFutureãSettableFuture 以åè¾
å©ç±»Futuresç,æ¹ä¾¿å¼æ¥ç¼ç¨ã
ä½ä¸ºæ£ç»çJavaç±»åºï¼æ¯ä¸æ¯åºè¯¥åç¹ä»ä¹ï¼å 强ä¸ä¸èªèº«åºçåè½å¢ï¼
å¨Java 8ä¸, æ°å¢å äºä¸ä¸ªå
å«50ä¸ªæ¹æ³å·¦å³çç±»: **CompletableFuture**ï¼æä¾äºé常强大çFutureçæ©å±åè½ï¼å¯ä»¥å¸®å©æä»¬ç®å弿¥ç¼ç¨ç夿æ§ï¼æä¾äºå½æ°å¼ç¼ç¨çè½åï¼å¯ä»¥éè¿åè°çæ¹å¼å¤ç计ç®ç»æï¼å¹¶ä¸æä¾äºè½¬æ¢åç»åCompletableFutureçæ¹æ³ã
æ¯å¦å®ç°ä¸é¢ä¸äºä¾å:
- å°ä¸¤ä¸ªå¼æ¥è®¡ç®å并为ä¸ä¸ªââè¿ä¸¤ä¸ªå¼æ¥è®¡ç®ä¹é´ç¸å¯¹ç¬ç«ï¼åæ¶ç¬¬äºä¸ªåä¾èµäºç¬¬ä¸ä¸ªçç»æ
- çå¾
Futureéåä¸çææä»»å¡é½å®æ
- ä»
çå¾
Futureéåä¸æå¿«ç»æçä»»å¡å®æï¼æå¯è½å 为å®ä»¬è¯å¾éè¿ä¸åçæ¹å¼è®¡ç®å ä¸ä¸ªå¼ï¼ï¼å¹¶è¿åå®çç»æ
- éè¿ç¼ç¨æ¹å¼å®æä¸ä¸ªFutureä»»å¡çæ§è¡ï¼å³ä»¥æå·¥è®¾å®å¼æ¥æä½ç»æçæ¹å¼ï¼
- åºå¯¹Futureç宿äºä»¶ï¼å³å½Futureç宿äºä»¶åçæ¶ä¼æ¶å°éç¥ï¼å¹¶è½ä½¿ç¨Future 计ç®çç»æè¿è¡ä¸ä¸æ¥çæä½ï¼ä¸åªæ¯ç®åå°é»å¡çå¾
æä½çç»æï¼
#### 1.2 使ç¨CompletableFuture æå»ºå¼æ¥åºç¨
```java
public class TestCompletableFuture {
public static CompletableFuture compute() {
final CompletableFuture future = new CompletableFuture<>();
return future;
}
public static void main(String[] args) throws Exception {
final CompletableFuture f = compute();
class Client extends Thread {
CompletableFuture f;
Client(String threadName, CompletableFuture f) {
super(threadName);
this.f = f;
}
@Override
public void run() {
try {
System.out.println(this.getName() + ": " + f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
new Client("Client1", f).start();
new Client("Client2", f).start();
System.out.println("waiting");
f.complete(100);
System.in.read();
}
}
```
------
## å
«ãæ°æ¶é´æ¥æ API
### 1. ä½¿ç¨ LocalDateãLocalTimeãLocalDateTime
- LocalDateãLocalTimeãLocalDateTime ç±»çå®ä¾æ¯**ä¸å¯åç对象**ï¼åå«è¡¨ç¤ºä½¿ç¨ ISO-8601æ¥åç³»ç»çæ¥æãæ¶é´ãæ¥æåæ¶é´ãå®ä»¬æä¾äºç®åçæ¥æææ¶é´ï¼å¹¶ä¸å
å«å½åçæ¶é´ä¿¡æ¯ãä¹ä¸å
å«ä¸æ¶åºç¸å
³çä¿¡æ¯ã
```java
@Test
public void test1(){
LocalDate date = LocalDate.of(2020,01,03);
Month month = date.getMonth();
System.out.println(month); //JANUARY
DayOfWeek dayOfWeek = date.getDayOfWeek();
System.out.println(dayOfWeek); //FRIDAY
int len = date.lengthOfMonth();
System.out.println(len); //31
//使ç¨TemporalField(ChronoFieldæä¸¾å®ç°äºè¯¥æ¥å£ï¼è¯»åLocalDateçå¼
int year = date.get(ChronoField.YEAR);
System.out.println(year); //2020
LocalDate ld = LocalDate.parse("2020-01-03");
System.out.println(ld); //2020-01-03
LocalTime time = LocalTime.of(19,56,11);
System.out.println(time); //19:56:11
LocalDateTime ldt = LocalDateTime.now();
LocalDateTime l1 = LocalDateTime.of(2020,01,03,18,48);
System.out.println(l1); //2020-01-03T18:48
LocalDateTime l2 = l1.plusYears(3);
System.out.println(l2); //2023-01-03T18:48
LocalDateTime l3 = l1.minusMonths(1);
System.out.println(l3); //2019-12-03T18:48
System.out.println(l3.getMinute()+","+l3.getYear()); //48,2019
}
```
### 2. Instant æ¶é´æ³
- ç¨äºâæ¶é´æ³âçè¿ç®ã宿¯ä»¥Unixå
å¹´(ä¼ ç»ç设å®ä¸ºUTCæ¶åº1970å¹´1æ1æ¥å夿¶å)å¼å§æç»åçç§æ°è¿è¡è®¡ç®
```java
@Test
public void test2(){
Instant ins = Instant.now(); //é»è®¤ä½¿ç¨ UTC æ¶åº
OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
System.out.println(odt);
System.out.println(ins.getNano());
Instant ins2 = Instant.ofEpochSecond(5);
System.out.println(ins2);
}
```
### 3. Duration å Period
- Duration:ç¨äºè®¡ç®ä¸¤ä¸ªâæ¶é´âé´é
- Period:ç¨äºè®¡ç®ä¸¤ä¸ªâæ¥æâé´é
```java
@Test
public void test3(){
Instant ins1 = Instant.now();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
Instant ins2 = Instant.now();
System.out.println("æèè´¹æ¶é´ä¸ºï¼" + Duration.between(ins1, ins2));
System.out.println("----------------------------------");
LocalDate ld1 = LocalDate.now();
LocalDate ld2 = LocalDate.of(2019, 1, 1);
Period pe = Period.between(ld2, ld1);
System.out.println(pe.getYears());
System.out.println(pe.getMonths());
System.out.println(pe.getDays());
}
```
### 4. æ¥æçæçºµ
- éè¿ withXXX æ¹æ³ä¿®æ¹ LocalDate ç屿§
- TemporalAdjuster : æ¶é´æ ¡æ£å¨ãææ¶æä»¬å¯è½éè¦è·åä¾å¦ï¼å°æ¥æè°æ´å°âä¸ä¸ªå¨æ¥âçæä½ã
- TemporalAdjusters : 该类éè¿éææ¹æ³æä¾äºå¤§éç常 ç¨ TemporalAdjuster çå®ç°ã
```java
@Test
public void test(){
LocalDate date = LocalDate.now();
//éè¿withAttributeræ¹æ³ä¿®æ¹LocalDateç屿§
LocalDate date1 = date.with(ChronoField.ALIGNED_WEEK_OF_YEAR,9);
LocalDate date2 = date.withYear(2019);
LocalDate date3 = date.withDayOfMonth(11); //ä¿®æ¹ä¸º11å·
System.out.println(date1);
//ä¸å¨æ¥
LocalDate nextSunday = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(nextSunday);
}
```
### 5. è§£æä¸æ ¼å¼å
`java.time.format.DateTimeFormatter` ç±»ï¼è¯¥ç±»æä¾äºä¸ç§æ ¼å¼åæ¹æ³ï¼
- é¢å®ä¹çæ åæ ¼å¼
- è¯è¨ç¯å¢ç¸å
³çæ ¼å¼
- èªå®ä¹çæ ¼å¼
```java
@Test
public void test(){
//DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE;
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyå¹´MMæddæ¥ HH:mm:ss E");
LocalDateTime ldt = LocalDateTime.now();
String strDate = ldt.format(dtf);
System.out.println(strDate); //2020å¹´01æ03æ¥ 20:32:14 ææäº
LocalDateTime newLdt = ldt.parse(strDate, dtf);
System.out.println(newLdt); //2020-01-03T20:32:14
}
```
#### æ¶åºçå¤ç
- Java8 ä¸å å
¥äºå¯¹æ¶åºçæ¯æï¼å¸¦æ¶åºçæ¶é´ä¸ºåå«ä¸ºï¼ ZonedDateãZonedTimeãZonedDateTime
å
¶ä¸æ¯ä¸ªæ¶åºé½å¯¹åºç IDï¼å°åºIDé½ä¸º â{åºå}/{åå¸}âçæ ¼å¼ ä¾å¦ ï¼Asia/Shanghai ç
ZoneIdï¼è¯¥ç±»ä¸å
å«äºææçæ¶åºä¿¡æ¯
- getAvailableZoneIds() : å¯ä»¥è·åæææ¶åºæ¶åºä¿¡æ¯
- of(id) : ç¨æå®çæ¶åºä¿¡æ¯è·å ZoneId 对象
```java
@Test
public void test(){
Set set = ZoneId.getAvailableZoneIds(); //éåæ¶åº
set.forEach(System.out::println);
LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println(ldt);
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("US/Pacific"));
System.out.println(zdt);
}
```
## ä¹ãé夿³¨è§£ä¸ç±»å注解
### 注解
Java 8 对注解å¤çæä¾äºä¸¤ç¹æ¹è¿ï¼**å¯éå¤ç注解**å**å¯ç¨äºç±»åçæ³¨è§£**
Java䏿³¨è§£æ¯ä¸ç§å¯¹ç¨åºå
ç´ è¿è¡é
ç½®ï¼æä¾éå ä¿¡æ¯çæºå¶ï¼Java8ä¹åï¼æ³¨è§£åªè½è¢«ç¨å¨å£°æä¸ï¼
### é夿³¨è§£

Java8 ä¹åä¸å
许ä¸è¾¹è¿æ ·çé夿³¨è§£ï¼æä»¥ä¸è¬ä¼éè¿ä¸äºæ¯ç¨ææ³ç»è¿è¿ä¸éå¶ãå¯ä»¥å£°æä¸ä¸ªæ°ç注解ï¼å®å
å«äºä½ 叿éå¤ç注解æ°ç»ã

#### å建ä¸ä¸ªé夿³¨è§£
1. å°æ³¨è§£æ 记为**@Repeatable**
2. æä¾ä¸ä¸ªæ³¨è§£ç容å¨
```java
import java.lang.annotation.Repeatable;
@Repeatable(Authors.class)
public @interface Author {
String name();
}
```
```java
public @interface Authors {
Author[] value();
}
```
```java
@Author(name = "Java")
@Author(name = "Android")
public class Book {
public static void main(String[] args) {
Author[] authors = Book.class.getAnnotationsByType(Author.class);
Arrays.asList(authors).forEach(s->{
System.out.println(s.name());
});
}
}
```
### ç±»åæ³¨è§£
Java8 å¼å§ï¼æ³¨è§£å¯ä»¥åºç¨äºä»»ä½ç±»åãå
æ¬newæä½ç¬¦ãç±»å转æ¢ãinstanceofæ£æ¥ãèåç±»ååæ°ï¼ä»¥åimplemtntsåthrowsåå¥ã
```java
@NotNull String name = person.getName(); //getNameä¸è¿å空
List<@NotNull Person> persons = new ArrayList<>(); //personsæ»æ¯é空
```
## åãå
¶ä»è¯è¨ç¹æ§
### ååæä½
`java.util.concurrent.atomic` å
æä¾äºå¤ä¸ªå¯¹æ°åç±»åè¿è¡æä½çç±»ï¼æ¯å¦AtomicIntegeråAtomicLongï¼å®ä»¬æ¯æå¯¹åä¸åéçååæä½ãè¿äºç±»å¨Java 8䏿°å¢äºæ´å¤çæ¹æ³æ¯æã
- getAndUpdateââ以ååæ¹å¼ç¨ç»å®çæ¹æ³æ´æ°å½åå¼ï¼å¹¶è¿ååæ´ä¹åçå¼
- updateAndGetââ以ååæ¹å¼ç¨ç»å®çæ¹æ³æ´æ°å½åå¼ï¼å¹¶è¿ååæ´ä¹åçå¼
- getAndAccumulateââ以ååæ¹å¼ç¨ç»å®çæ¹æ³å¯¹å½ååç»å®çå¼è¿è¡æ´æ°ï¼å¹¶è¿ååæ´ä¹åçå¼
- accumulateAndGetââ以ååæ¹å¼ç¨ç»å®çæ¹æ³å¯¹å½ååç»å®çå¼è¿è¡æ´æ°ï¼å¹¶è¿ååæ´ä¹åçå¼
**AdderåAccumulator**
å¤çº¿ç¨çç¯å¢ä¸ï¼å¦æå¤ä¸ªçº¿ç¨éè¦é¢ç¹å°è¿è¡æ´æ°æä½ï¼ä¸å¾å°æè¯»åçå¨ä½(æ¯å¦ï¼å¨ç»è®¡è®¡ç®çä¸ä¸æä¸)ï¼Java APIææ¡£ä¸æ¨èå¤§ä½¿ç¨æ°çç±»LongAdderãLongAccumulatorãDouble-Adder以åDoubleAccumulatorï¼å°½éé¿å
使ç¨å®ä»¬å¯¹åºçååç±»åãè¿äºæ°çç±»å¨è®¾è®¡ä¹åå°±èèäºå¨æå¢é¿çéæ±ï¼å¯ä»¥ææå°åå°çº¿ç¨é´çç«äºã
LongAddr å DoubleAdder ç±»é½æ¯æå æ³æä½ ï¼ è LongAccumulator å DoubleAccumulatorå¯ä»¥ä½¿ç¨ç»å®çæ¹æ³æ´åå¤ä¸ªå¼ã
### ConcurrentHashMap
ConcurrentHashMapç±»çå¼å
¥æå¤§å°æåäºHashMapç°ä»£åçç¨åº¦ï¼æ°å¼å
¥çConcurrentHashMap对并åçæ¯æé常å好ãConcurrentHashMapå
许并åå°è¿è¡æ°å¢åæ´æ°æä½ï¼å 为å®ä»
对å
鍿°æ®ç»æçæäºé¨åä¸éãå æ¤ï¼åå¦ä¸ç§éæ©ï¼å³åæ¥å¼çHashtableæ¯è¾èµ·æ¥ï¼å®å
·ææ´é«çè¯»åæ§è½ã
1. **æ§è½**
ä¸ºäºæ¹åæ§è½ï¼è¦å¯¹ConcurrentHashMapçå
鍿°æ®ç»æè¿è¡è°æ´ãå
¸åæ
åµä¸ï¼mapçæ¡ç®ä¼è¢«åå¨å¨æ¡¶ä¸ï¼ä¾æ®é®çæåå¸å¼è¿è¡è®¿é®ã使¯ï¼å¦æå¤§éé®è¿åç¸åçåå¸å¼ï¼ç±äºæ¡¶æ¯ç±Listå®ç°çï¼å®çæ¥è¯¢å¤æåº¦ä¸ºO(n)ï¼è¿ç§æ
åµä¸æ§è½ä¼æ¶åãå¨Java 8ä¸ï¼å½æ¡¶è¿äºèè¿æ¶ï¼å®ä»¬ä¼è¢«å¨æå°æ¿æ¢ä¸ºæåºæ (sorted tree)ï¼æ°çæ°æ®ç»æå
·ææ´å¥½çæ¥è¯¢æ§è½(æåºæ çæ¥è¯¢å¤æåº¦ä¸ºO(log(n)))ãæ³¨æï¼è¿ç§ä¼ååªæå½é®æ¯å¯ä»¥æ¯è¾ç(æ¯å¦Stringæè
Numberç±»)æ¶æå¯è½åçã
2. **ç±»æµæä½**
ConcurrentHashMapæ¯æä¸ç§æ°çæä½ï¼è¿äºæä½åä½ ä¹å卿µä¸æè§çå¾å:
- forEachââ对æ¯ä¸ªé®å¼å¯¹è¿è¡ç¹å®çæä½
- reduceââ使ç¨ç»å®çô°¤ç®å½æ°(reduction function)ï¼å°ææçé®å¼å¯¹æ´ååºä¸ä¸ªç»æô°
- searchââ对æ¯ä¸ä¸ªé®å¼å¯¹æ§è¡ä¸ä¸ªå½æ°ï¼ç´å°å½æ°çè¿åå¼ä¸ºä¸ä¸ªé空å¼
以䏿¯ä¸ç§æä½é½æ¯æåç§å½¢å¼ï¼æ¥å使ç¨é®ãå¼ãMap.Entry以åé®å¼å¯¹ç彿°:
- 使ç¨é®åå¼çæä½(forEachãreduceãsearch)
- 使ç¨é®çæä½(forEachKeyãreduceKeysãsearchKeys)
- 使ç¨å¼çæä½ (forEachValueãreduceValuesãsearchValues)
- 使ç¨Map.Entry对象çæä½(forEachEntryãreduceEntriesãsearchEntries)
注æï¼è¿äºæä½ä¸ä¼å¯¹ConcurrentHashMapçç¶æä¸éãå®ä»¬åªä¼å¨è¿è¡è¿ç¨ä¸å¯¹å
ç´ è¿è¡æä½ãåºç¨å°è¿äºæä½ä¸ç彿°ä¸åºè¯¥å¯¹ä»»ä½ç顺åºï¼æè
å
¶ä»å¯¹è±¡ï¼æå¨è®¡ç®è¿ç¨åçååçå¼ï¼æä¾èµã 餿¤ä¹å¤ï¼ä½ éè¦ä¸ºè¿äºæä½æå®ä¸ä¸ªå¹¶åéå¼ã妿ç»è¿é¢é¢ä¼°å½åmapç大å°å°äºè®¾å®çéå¼ï¼æä½ä¼é¡ºåºæ§è¡ã使ç¨å¼1å¼å¼å¯åºäºéç¨çº¿ç¨æ± çæå¤§å¹¶è¡ã使ç¨å¼Long.MAX_VALUE设å®ç¨åºä»¥åçº¿ç¨æ§è¡æä½ãä¸é¢è¿ä¸ªä¾åä¸ï¼æä»¬ä½¿ç¨reduceValuesè¯å¾æ¾åºmapä¸çæå¤§å¼:
```java
ConcurrentHashMap map = new ConcurrentHashMap<>();
Optional maxValue = Optional.of(map.reduceValues(1, Integer::max));
```
注æï¼å¯¹intãlongådoubleï¼å®ä»¬çreduceæä½åæä¸å(æ¯å¦reduceValuesToIntãreduceKeysToLongç)ã
3. 计æ°
ConcurrentHashMapç±»æä¾äºä¸ä¸ªæ°çæ¹æ³ï¼åå«**mappingCount**ï¼å®ä»¥é¿æ´ålongè¿åmap䏿 å°çæ°ç®ãæä»¬åºè¯¥å°½é使ç¨è¿ä¸ªæ°æ¹æ³ï¼è䏿¯èçsizeæ¹æ³ï¼sizeæ¹æ³è¿åçç±»å为intãè¿æ¯å 为æ å°çæ°éå¯è½æ¯intæ æ³è¡¨ç¤ºçã
4. éåè§å¾
ConcurrentHashMapç±»è¿æä¾äºä¸ä¸ªå为**KeySet**çæ°æ¹æ³ï¼è¯¥æ¹æ³ä»¥Setçå½¢å¼è¿åConcurrentHashMapçä¸ä¸ªè§å¾(对mapçä¿®æ¹ä¼åæ å¨è¯¥Setä¸ï¼åä¹äº¦ç¶)ãä½ ä¹å¯ä»¥ä½¿ç¨æ°çéææ¹æ³**newKeySet**ï¼ç±ConcurrentHashMapå建ä¸ä¸ªSetã
### Arrays
Arraysç±»æä¾äºä¸åçéææ¹æ³å¯¹æ°ç»è¿è¡æä½ãç°å¨ï¼å®åå
æ¬äºå个æ°çæ¹æ³(å®ä»¬é½æç¹å«éè½½çåé)
- **parallelSort**ï¼parallelSortæ¹æ³ä¼ä»¥å¹¶åçæ¹å¼å¯¹æå®çæ°ç»è¿è¡æåºï¼ä½ å¯ä»¥ä½¿ç¨èªç¶é¡ºåºï¼ä¹å¯ä»¥
为æ°ç»å¯¹è±¡å®ä¹ç¹å«çComparator
- **setAllåparallelSetAll**ï¼setAllåparallelSetAllæ¹æ³å¯ä»¥ä»¥é¡ºåºçæ¹å¼ä¹å¯ä»¥ç¨å¹¶åçæ¹å¼ï¼ä½¿ç¨æä¾ç彿° è®¡ç®æ¯ä¸ä¸ªå
ç´ çå¼ï¼å¯¹æå®æ°ç»ä¸çææå
ç´ è¿è¡è®¾ç½®
- **parallelPrefix**ï¼parallelPrefixæ¹æ³ä»¥å¹¶åçæ¹å¼ï¼ç¨ç¨æ·æä¾çäºè¿å¶æä½ç¬¦å¯¹ç»å®æ°ç»ä¸çæ¯ä¸ªå
ç´
è¿è¡ç´¯ç§¯è®¡ç®
### Number
Numberç±»ä¸æ°å¢æ¹æ³
- ShortãIntegerãLongãFloatåDoubleç±»æä¾äºéææ¹æ³sumãminåmax
- IntegeråLongç±»æä¾äºcompareUnsignedãdivideUnsignedãremainderUnsigned åtoUnsignedLongæ¹æ³æ¥å¤çæ ç¬¦å·æ°ã
- IntegeråLongç±»ä¹å嫿ä¾äºéææ¹æ³parseUnsignedIntåparseUnsignedLong å°å符解æä¸ºæ 符å·intæè
longç±»åã
- ByteåShortç±»æä¾äºtoUnsignedIntåtoUnsignedLongæ¹æ³éè¿æ 符å·è½¬æ¢å°åæ°è½¬å为 int æ è
long ç±»åã类似å°ï¼ Integer ç±»ç°å¨ä¹æä¾äºéææ¹æ³ toUnsignedLongã
- DoubleåFloatç±»æä¾äºéææ¹æ³isFiniteï¼å¯ä»¥æ£æ¥åæ°æ¯å¦ä¸ºæéæµ®ç¹æ°ã
- Booleanç±»ç°å¨æä¾äºéææ¹æ³logicalAndãlogicalOrålogicalXorï¼å¯ä»¥å¨ä¸¤ä¸ª booleanä¹é´æ§è¡andãoråxoræä½ã
- BigInteger ç±»æä¾äº byteValueExact ã shortValueExact ã intValueExact å longValueExactï¼å¯ä»¥å°BigIntegerç±»åçå¼è½¬æ¢ä¸ºå¯¹åºçåºç¡ç±»åãä¸è¿ï¼å¦æå¨è½¬æ¢è¿ç¨ä¸æä¿¡æ¯çä¸¢å¤±ï¼æ¹æ³ä¼æåºç®æ¯å¼å¸¸ã
### Math
妿Mathä¸çæ¹æ³å¨æä½ä¸åºç°àº¼åºï¼Mathç±»æä¾äºæ°çæ¹æ³å¯ä»¥æåºç®æ¯å¼å¸¸ãæ¯æè¿ä¸å¼å¸¸çæ¹æ³å
æ¬ä½¿ç¨intålongåæ°çaddExactãsubtractExactãmultipleExactã incrementExactãdecrementExactånegateExactãæ¤å¤ï¼Mathç±»è¿æ°å¢äºä¸ä¸ªéææ¹æ³ toIntExactï¼å¯ä»¥å°longå¼è½¬æ¢ä¸ºintå¼ãå
¶ä»çæ°å¢å
容å
æ¬éææ¹æ³floorModãfloorDiv ånextDownã
### Files
Filesç±»æå¼äººæ³¨ç®çæ¹åæ¯ï¼ä½ ç°å¨å¯ä»¥ç¨æä»¶ç´æ¥äº§çæµ
- Files.listââçæç±æå®ç®å½ä¸æææ¡ç®ææçStream\ãè¿ä¸ªåè¡¨ä¸æ¯éå½å
å«çãç±äºæµæ¯å»¶è¿æ¶è´¹çï¼å¤çå
å«å
容é常åºå¤§çç®å½æ¶ï¼è¿ä¸ªæ¹æ³é常æç¨
- Files.walkââåFiles.listæäºç±»ä¼¼ï¼å®ä¹çæå
å«ç»å®ç®å½ä¸æææ¡ç®ç Stream\ãä¸è¿è¿ä¸ªå表æ¯éå½çï¼ä½ å¯ä»¥è®¾å®éå½çæ·±åº¦ãæ³¨æï¼è¯¥é忝ä¾ç
§æ·±åº¦ä¼å
è¿è¡ç
- Files.findââ éè¿éå½å°éåä¸ä¸ªç®å½æ¾å°ç¬¦åæ¡ä»¶çæ¡ç®ï¼å¹¶çæä¸ä¸ª Stream\ 对象
### String
Stringç±»ä¹æ°å¢ô±äºä¸ä¸ªéææ¹æ³ï¼åå«joinãå®å¯ä»¥ç¨ä¸ä¸ªåé符å°å¤ä¸ªå符串ô¶æ¥èµ·æ¥ãåæä»¬ä»¥å使ç¨çapacheæä¾ç`StringUtils.join`䏿 ·ã
### Reflection
Reflection APIçååå°±æ¯ä¸ºäºæ¯æJava 8䏿³¨è§£æºå¶çæ¹åã 餿¤ä¹å¤ï¼Relectionæ¥å£çå¦ä¸ä¸ªå忝**æ°å¢äºå¯ä»¥æ¥è¯¢æ¹æ³åæ°ä¿¡æ¯çAPI**ï¼æ¯å¦ï¼ä½ ç°å¨å¯ä»¥ä½¿ç¨æ°ç`java.lang.reflect.Parameter`ç±»æ¥è¯¢æ¹æ³åæ°çåç§°å修饰符ã
------
## FAQ

- è¯´è¯´ä½ ç¥éçJava8 æåªåæ°ç¹æ§ï¼
- ä»ä¹æ¯lambda表达å¼ï¼æå¥ä¼ç¹ï¼
- ConcurrentHashMap å¨Java8 å Java7çå®ç°åºå«ï¼
- è½è¯´è¯´ Java 8 æ¹è¿çJVM ä¸?
- hashMapåçï¼java8åäºåªäºæ¹åï¼
- å¤é¨è¿ä»£åå
é¨è¿ä»£ï¼ä½ æå¾å§ï¼
------
## åè
ãJava 8宿ã
ãJava 8彿°å¼ç¼ç¨ã
Java 8宿¹ææ¡£
æå
è´¹è§é¢å¦ä¹ ç½ç«