diff --git a/pom.xml b/pom.xml
index 10e5035e..dc64656c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,8 +37,8 @@
maven-compiler-plugin
3.1
- 1.9
- 1.9
+ 9
+ 9
diff --git a/src/main/java/lambdasinaction/TestMain.java b/src/main/java/lambdasinaction/TestMain.java
new file mode 100644
index 00000000..ed389b3f
--- /dev/null
+++ b/src/main/java/lambdasinaction/TestMain.java
@@ -0,0 +1,45 @@
+package lambdasinaction;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+/**
+ * 功能说明:
+ * 系统版本: v1.0
+ * 开发人员: @author yejg
+ * 开发时间: 2018年11月08日
+ */
+public class TestMain {
+
+ public static void main(String[] args) {
+ long fastest = Long.MAX_VALUE;
+ Map sourceMap = new HashMap();
+ for (int i = 0; i < 5000; i++) {
+ sourceMap.put("" + i, "" + i);
+ }
+ long start = System.nanoTime();
+ for (int i = 0; i < 10; i++) {
+ sourceMap.entrySet().parallelStream().forEach(e -> System.out.print(e.getKey() + " "));
+ System.out.println();
+ long duration = (System.nanoTime() - start) / 1_000_000;
+ if (duration < fastest) {
+ fastest = duration;
+ }
+ System.out.println("done in " + duration);
+ }
+ System.out.println("fast in " + fastest);
+ }
+}
+
+// Map stringMap = Stream.generate(() -> {
+// Map tmpMap = new HashMap();
+// tmpMap.put("1", "1");
+// return tmpMap;
+// }).limit(20).flatMap(x -> x.entrySet().stream()).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
+//
+// stringMap.entrySet().stream().forEach(x-> System.out.println(x.getKey()));
\ No newline at end of file
diff --git a/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java
index d2940969..2bf75fcf 100644
--- a/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java
+++ b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java
@@ -7,19 +7,16 @@
public class OperationsWithOptional {
- public static void main(String... args) {
- System.out.println(max(of(3), of(5)));
- System.out.println(max(empty(), of(5)));
+ public static void main(String... args) {
+ System.out.println(max(of(3), of(5)));
+ System.out.println(max(empty(), of(5)));
- Optional opt1 = of(5);
- Optional opt2 = opt1.or(() -> of(4));
+ Optional opt1 = of(5);
+// Optional opt2 = opt1.or(() -> of(4));
+// System.out.println(of(5).or(() -> of(4)));
+ }
- System.out.println(
- of(5).or(() -> of(4))
- );
- }
-
- public static final Optional max(Optional i, Optional j) {
- return i.flatMap(a -> j.map(b -> Math.max(a, b)));
- }
+ public static final Optional max(Optional i, Optional j) {
+ return i.flatMap(a -> j.map(b -> Math.max(a, b)));
+ }
}
diff --git a/src/main/java/lambdasinaction/chap11/BestPriceFinder.java b/src/main/java/lambdasinaction/chap11/BestPriceFinder.java
index 51412e93..93856ac1 100644
--- a/src/main/java/lambdasinaction/chap11/BestPriceFinder.java
+++ b/src/main/java/lambdasinaction/chap11/BestPriceFinder.java
@@ -55,6 +55,10 @@ public Stream> findPricesStream(String product) {
return shops.stream()
.map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice(product), executor))
.map(future -> future.thenApply(Quote::parse))
+ // thenCompose方法允许你对两个异步操作进行流水线,第一个操作完成时,将其结果作为参数传递给第二个操作
+ // thenComposeAsync、thenApplyAsync
+ // 名称中不带Async的方法和它的前一个任务一样,在同一个线程中运行;
+ // 而名称以Async结尾的方法会将后续的任务提交到一个线程池,所以每个任务是由不同的线程处理的。
.map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote), executor)));
}
diff --git a/src/main/java/lambdasinaction/chap12/DateTimeExamples.java b/src/main/java/lambdasinaction/chap12/DateTimeExamples.java
index 46895cc5..16544230 100644
--- a/src/main/java/lambdasinaction/chap12/DateTimeExamples.java
+++ b/src/main/java/lambdasinaction/chap12/DateTimeExamples.java
@@ -1,8 +1,5 @@
package lambdasinaction.chap12;
-import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
-import static java.time.temporal.TemporalAdjusters.nextOrSame;
-
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
@@ -12,6 +9,9 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
import java.time.chrono.JapaneseDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
@@ -22,20 +22,81 @@
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
+import java.util.TimeZone;
+
+import static java.time.temporal.TemporalAdjusters.dayOfWeekInMonth;
+import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
+import static java.time.temporal.TemporalAdjusters.nextOrSame;
public class DateTimeExamples {
+ private static final ThreadLocal formatters2 = new ThreadLocal();
+
+ static {
+ System.out.println("static code...");
+ formatters2.set(new SimpleDateFormat("dd-MMM-yyyy"));
+ }
+
private static final ThreadLocal formatters = new ThreadLocal() {
protected DateFormat initialValue() {
+ System.out.println("initialValue...");
return new SimpleDateFormat("dd-MMM-yyyy");
}
};
public static void main(String[] args) {
+ System.out.println("main...");
+
+ usePeriod();
+ useZoneId();
+
useOldDate();
useLocalDate();
useTemporalAdjuster();
useDateFormatter();
+
+ Date dateNow = localDateTime2Date(LocalDateTime.now());
+ LocalDateTime localDateTimeNow = date2LocalDateTime(dateNow);
+ System.out.println("done.");
+ }
+
+
+ public static Date localDateTime2Date(LocalDateTime localDateTime) {
+ ZoneId zoneId = ZoneId.systemDefault();
+ ZonedDateTime zdt = localDateTime.atZone(zoneId);
+ Date date = Date.from(zdt.toInstant());
+ System.out.println(date.toString());
+ return date;
+ }
+
+ public static LocalDateTime date2LocalDateTime(Date date) {
+ ZoneId zoneId = ZoneId.systemDefault();
+ Instant instant = date.toInstant();
+ LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
+ return localDateTime;
+ }
+
+ private static void useZoneId() {
+ ZoneId zoneId = TimeZone.getDefault().toZoneId();
+ ZoneId romeZone = ZoneId.of("Europe/Rome");
+ LocalDate date = LocalDate.of(2014, Month.MARCH, 18);
+ ZonedDateTime zdt1 = date.atStartOfDay(romeZone);
+ LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
+ ZonedDateTime zdt2 = dateTime.atZone(romeZone);
+ Instant instant = Instant.now();
+ ZonedDateTime zdt3 = instant.atZone(romeZone);
+ }
+
+ private static void usePeriod() {
+ Period period = Period.of(2018, 11, 30);
+
+ Period between = Period.between(LocalDate.of(2018, 11, 29), LocalDate.of(2018, 11, 30));
+ System.out.println(between.getDays());
+
+ // 由于Duration类主要用于以秒和纳 秒衡量时间的长短,你不能向between方法传递LocalDate对象做参数
+ // Duration duration = Duration.between(LocalDate.of(2018, 11, 19), LocalDate.of(2018, 11, 30));// error
+ Duration duration = Duration.between(LocalTime.of(13, 45, 20), LocalTime.of(13, 45, 19));
+ duration.getSeconds();
}
private static void useOldDate() {
@@ -45,13 +106,13 @@ private static void useOldDate() {
System.out.println(formatters.get().format(date));
Calendar calendar = Calendar.getInstance();
- calendar.set(2014, Calendar.FEBRUARY, 18);
+ calendar.set(2018, Calendar.FEBRUARY, 18);
System.out.println(calendar);
}
private static void useLocalDate() {
- LocalDate date = LocalDate.of(2014, 3, 18);
- int year = date.getYear(); // 2014
+ LocalDate date = LocalDate.of(2018, 3, 18);
+ int year = date.getYear(); // 2018
Month month = date.getMonth(); // MARCH
int day = date.getDayOfMonth(); // 18
DayOfWeek dow = date.getDayOfWeek(); // TUESDAY
@@ -69,7 +130,8 @@ private static void useLocalDate() {
int second = time.getSecond(); // 20
System.out.println(time);
- LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20); // 2014-03-18T13:45
+ LocalDateTime localDateTime = LocalDateTime.parse("20181130140100", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+ LocalDateTime dt1 = LocalDateTime.of(2018, Month.MARCH, 18, 13, 45, 20); // 2018-03-18T13:45
LocalDateTime dt2 = LocalDateTime.of(date, time);
LocalDateTime dt3 = date.atTime(13, 45, 20);
LocalDateTime dt4 = date.atTime(time);
@@ -97,7 +159,10 @@ private static void useLocalDate() {
}
private static void useTemporalAdjuster() {
- LocalDate date = LocalDate.of(2014, 3, 18);
+ LocalDate date = LocalDate.of(2018, 11, 30);
+ TemporalAdjuster adjuster = dayOfWeekInMonth(1, DayOfWeek.MONDAY);
+ LocalDate with = date.with(adjuster);
+
date = date.with(nextOrSame(DayOfWeek.SUNDAY));
System.out.println(date);
date = date.with(lastDayOfMonth());
@@ -122,6 +187,7 @@ private static void useTemporalAdjuster() {
System.out.println(date);
}
+ // 自定义TemporalAdjuster
private static class NextWorkingDay implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
@@ -134,7 +200,7 @@ public Temporal adjustInto(Temporal temporal) {
}
private static void useDateFormatter() {
- LocalDate date = LocalDate.of(2014, 3, 18);
+ LocalDate date = LocalDate.of(2018, 3, 18);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.ITALIAN);
diff --git a/src/main/java/lambdasinaction/chap2/FilteringApples.java b/src/main/java/lambdasinaction/chap2/FilteringApples.java
index 0f61fd08..f328749b 100644
--- a/src/main/java/lambdasinaction/chap2/FilteringApples.java
+++ b/src/main/java/lambdasinaction/chap2/FilteringApples.java
@@ -1,12 +1,28 @@
package lambdasinaction.chap2;
import java.util.*;
+import java.util.stream.Collectors;
public class FilteringApples{
public static void main(String ... args){
- List inventory = Arrays.asList(new Apple(80,"green"), new Apple(155, "green"), new Apple(120, "red"));
+ List inventory = Arrays.asList(new Apple(80,"green"), new Apple(155, "green"), new Apple(120, "red"));
+
+ List collect = inventory.stream().filter(apple -> apple.getWeight() > 80).collect(Collectors.toList());
+ collect.stream().forEach(System.out::println);
+
+ System.out.println("----------------");
+ inventory.stream().sorted((a1,a2) -> a1.getWeight().compareTo(a2.getWeight())).forEach(System.out::println);
+ System.out.println("----------------");
+ inventory.stream().sorted(Comparator.comparing(Apple::getWeight).reversed()).forEach(System.out::println);
+ System.out.println("----------------");
+ inventory.stream().forEach(System.out::println);// 顺序遍历打印
+ System.out.println("----------------");
+ inventory.parallelStream().forEach(System.out::println);// 并行遍历打印,顺序随机
+
+ System.out.println("----------------");
+
// [Apple{color='green', weight=80}, Apple{color='green', weight=155}]
List greenApples = filterApplesByColor(inventory, "green");
diff --git a/src/main/java/lambdasinaction/chap3/ExecuteAround.java b/src/main/java/lambdasinaction/chap3/ExecuteAround.java
index 6c15fb6a..93932acc 100644
--- a/src/main/java/lambdasinaction/chap3/ExecuteAround.java
+++ b/src/main/java/lambdasinaction/chap3/ExecuteAround.java
@@ -4,6 +4,9 @@
public class ExecuteAround {
public static void main(String ...args) throws IOException{
+ String path = "src/main/resources/lambdasinaction/chap3/data.txt";
+ File f = new File(path);
+ System.out.println(f.getAbsolutePath());
// method we want to refactor to make more flexible
String result = processFileLimited();
@@ -17,6 +20,10 @@ public static void main(String ...args) throws IOException{
String twoLines = processFile((BufferedReader b) -> b.readLine() + b.readLine());
System.out.println(twoLines);
+ System.out.println("-----------------------------");
+ BufferedReaderProcessor processor = (BufferedReader b) -> b.readLine();
+ String s = processor.process(new BufferedReader(new FileReader("lambdasinaction/chap3/data.txt")));
+ System.out.println(s);
}
public static String processFileLimited() throws IOException {
@@ -34,6 +41,7 @@ public static String processFile(BufferedReaderProcessor p) throws IOException {
}
+ @FunctionalInterface
public interface BufferedReaderProcessor{
public String process(BufferedReader b) throws IOException;
diff --git a/src/main/java/lambdasinaction/chap3/data1.txt b/src/main/java/lambdasinaction/chap3/data1.txt
new file mode 100644
index 00000000..20764bbf
--- /dev/null
+++ b/src/main/java/lambdasinaction/chap3/data1.txt
@@ -0,0 +1,5 @@
+Java
+8
+Lambdas
+In
+Action
\ No newline at end of file
diff --git a/src/main/java/lambdasinaction/chap6/Grouping.java b/src/main/java/lambdasinaction/chap6/Grouping.java
index 9105cc80..48d96b43 100644
--- a/src/main/java/lambdasinaction/chap6/Grouping.java
+++ b/src/main/java/lambdasinaction/chap6/Grouping.java
@@ -33,12 +33,13 @@ private static Map> groupDishNamesByType() {
}
private static Map> groupDishTagsByType() {
- return menu.stream().collect(groupingBy(Dish::getType, flatMapping(dish -> dishTags.get( dish.getName() ).stream(), toSet())));
+ // flatMapping since jdk 9
+ return menu.stream().collect(groupingBy(Dish::getType, flatMapping((Dish dish) -> dishTags.get( dish.getName() ).stream(), toSet())));
}
private static Map> groupCaloricDishesByType() {
// return menu.stream().filter(dish -> dish.getCalories() > 500).collect(groupingBy(Dish::getType));
- return menu.stream().collect(groupingBy(Dish::getType, filtering(dish -> dish.getCalories() > 500, toList())));
+ return menu.stream().collect(groupingBy(Dish::getType, filtering((Dish dish) -> dish.getCalories() > 500, toList())));
}
private static Map> groupDishesByCaloricLevel() {
diff --git a/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java b/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java
index 69d7c4ca..39b6cdd7 100644
--- a/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java
+++ b/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java
@@ -9,98 +9,98 @@
public class PartitionPrimeNumbers {
- public static void main(String ... args) {
- System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimes(100));
- System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimesWithCustomCollector(100));
+ public static void main(String ... args) {
+ System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimes(100));
+ System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimesWithCustomCollector(100));
- }
+ }
- public static Map> partitionPrimes(int n) {
- return IntStream.rangeClosed(2, n).boxed()
- .collect(partitioningBy(candidate -> isPrime(candidate)));
- }
+ public static Map> partitionPrimes(int n) {
+ return IntStream.rangeClosed(2, n).boxed()
+ .collect(partitioningBy(candidate -> isPrime(candidate)));
+ }
- public static boolean isPrime(int candidate) {
- return IntStream.rangeClosed(2, candidate-1)
- .limit((long) Math.floor(Math.sqrt((double) candidate)) - 1)
- .noneMatch(i -> candidate % i == 0);
- }
+ public static boolean isPrime(int candidate) {
+ return IntStream.rangeClosed(2, candidate-1)
+ .limit((long) Math.floor(Math.sqrt((double) candidate)) - 1)
+ .noneMatch(i -> candidate % i == 0);
+ }
- public static Map> partitionPrimesWithCustomCollector(int n) {
- return IntStream.rangeClosed(2, n).boxed().collect(new PrimeNumbersCollector());
- }
+ public static Map> partitionPrimesWithCustomCollector(int n) {
+ return IntStream.rangeClosed(2, n).boxed().collect(new PrimeNumbersCollector());
+ }
- public static boolean isPrime(List primes, Integer candidate) {
- double candidateRoot = Math.sqrt((double) candidate);
- //return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0);
- return primes.stream().takeWhile(i -> i <= candidateRoot).noneMatch(i -> candidate % i == 0);
- }
+ public static boolean isPrime(List primes, Integer candidate) {
+ double candidateRoot = Math.sqrt((double) candidate);
+ //return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0);
+ return primes.stream().takeWhile(i -> i <= candidateRoot).noneMatch(i -> candidate % i == 0);
+ }
/*
- public static List takeWhile(List list, Predicate p) {
- int i = 0;
- for (A item : list) {
- if (!p.test(item)) {
- return list.subList(0, i);
- }
- i++;
- }
- return list;
- }
+ public static List takeWhile(List list, Predicate p) {
+ int i = 0;
+ for (A item : list) {
+ if (!p.test(item)) {
+ return list.subList(0, i);
+ }
+ i++;
+ }
+ return list;
+ }
*/
- public static class PrimeNumbersCollector
- implements Collector>, Map>> {
+ public static class PrimeNumbersCollector
+ implements Collector>, Map>> {
- @Override
- public Supplier