《Java8實戰》讀書筆記

#1. Java8 引入更多編程概念、編程工具,簡潔、靈活地編寫代碼。java

優化步驟:
1)進一步複用代碼,抽取公共的邏輯代碼,參數化可變的邏輯代碼
2)聲明式編程
3)併發編程,隱藏底層實現
##1.1 lambda表達式 進一步複用邏輯代碼,行爲參數化,引入函數式編程思想。數據庫

###lambda表達式 相較於以前的匿名類實現行爲參數化,更簡潔 。有參數列表、箭頭、函數主體、返回類型、異常列表。express

(parameters)->expression
(parameters)->{statements;}

###函數式接口
1)函數式接口:只定義一個抽象方法的接口,一般會使用@FunctionalInterface註解一下;
2)lambda表達式能夠看成函數式接口的實現實例;
3)經常使用的函數式接口:在java.util.function包預約義了一些經常使用函數式接口:編程

Predicate<T> {	boolean test(T t);	}
Consumer<T> {	void accept(T t);	}
Function<T,R> {	R apply(T t);	}
Supplier<T>	{	T get();	}
UnaryOperate<T>	extends Function<T, T>{}
BinaryOperator<T> extends BiFunction<T,T,T>{}
BiPredicate<L,R> {	boolean test(T t, U u);	}
BiConsumer<T,U>	{	void accept(T t, U u);	}
BiFunction<T,U,R> {	R apply(T t, U u);	}

4)原型類型特化的函數式接口:避免裝箱、拆箱操做,輸入參數或返回類型是原始類型;數組

###類型堅持、類型推斷以及限制
1)lambda類型檢查:lambda的類型是從使用lambda的上下文推斷出來的,目標類型的抽象方法簽名(函數描述符)能夠兼容lambda表達式的簽名。另外若是一個lambda的主體是一個語句表達式,它就和一個返回void的函數描述符兼容。
2)lambda類型推斷以:既然能夠推斷出lambda的簽名,就能夠知道lambda表達式的參數類型,省去lambda中參數類型的書寫。
3)限制:使用自由變量,即外層做用域中定義的變量,必須聲明稱final數據結構

###方法引用 方法引用:能夠被看做僅僅調用特定方法的lambda的一種快捷寫法,能夠重複使用現有的方法來建立lambda表達式。有:
1)指向靜態方法的方法引用;
2)指向任意類型實例方法的方法引用;
3)指向現有對象的實例方法的方法引用;
4)構造函數引用併發

###複合lambda高階函數app

##1.2 流Stream 不少業務邏輯都涉及相似數據庫的集合操做,都會使用到Collection。Collection主要是爲了存儲和訪問數據,Stream主要用於描述對數據集合Collection的計算處理(聲明式處理數據集合,能夠透明地並行處理)。框架

流:從支持數據處理操做的源生成的元素序列。 特色:1)按需計算,能夠是無界的,延遲;2)只能遍歷一次;3)內部迭代。異步

使用流:1)一個數據源來執行一個查詢;2)一箇中間操做鏈,造成一個流的流水線;3)一個終端操做,只想流水線,並能生成結果。

默認方法: java8在加入Stream時,在原來的集合系統上使用了「默認方法」得以擴展Stream功能而不用每一個實現類都實現相關接口方法。

###構建流 原始類型特化流:IntStream, DoubleStream, LongStream避免裝箱成本。1)每一個接口都帶來性的經常使用的數值歸約方法。 2)Stream提供mapToXXX轉成特化流,特化流經過boxed轉回對象流。3)提供range和rangeClosed生成流。

構建方法:1)由值建立:Stream.of();2)由數組構建:Arrays.Stream();3)由文件生成:Files.line();4)由函數生成:Stream.iterate, Stream.generate

###使用流 Stream接口的方法
1)篩選和切片:filter, distinct, limit, skip ;
2)映射:map, flatMap(把一個流中的每一個值都轉成另外一個流,而後把全部的流鏈接起來成爲一個流);
3)查找和匹配:allMatch, anyMatch, noneMatch, findFirst, findAny;
4)歸約摺疊:reduce,能夠支持並行計算,collect;

###用流收集數據 1)collect是一個終端操做,參數是將流中元素累計到彙總結果的各類方式(收集器)
1)預約義收集器:Collector類提供的工廠方法建立的收集器:3大功能:將流元素歸約和彙總爲一個值;元素分組groupingBy;元素分區partitioningBy。收集器能夠複合起來進行多級分組、分區和歸約。
2)自定義收集器:

public interface Collector<T, A, R> {    
    Supplier<A> supplier();    
    BiConsumer<A, T> accumulator();
    BinaryOperator<A> combiner();
    Function<A, R> finisher();
    Set<Characteristics> characteristics();
    public static<T, R> Collector<T, R, R> of(Supplier<R> supplier,
                                              BiConsumer<R, T> accumulator,
                                              BinaryOperator<R> combiner,
                                              Characteristics... characteristics) {... }

    public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
                                                 BiConsumer<A, T> accumulator,
                                                 BinaryOperator<A> combiner,
                                                 Function<A, R> finisher,
                                                 Characteristics... characteristics) {...}

    
}

###並行流 底層使用分支/合併框架處理並行流,用遞歸方式將能夠並行的任務拆分紅更小的任務,在不一樣的線程上執行,而後將各個子任務的結果合併起來生成總體結果。

高效使用並行流
1)使用適當的基準來檢查並行流性能;
2)留意裝箱。自動裝箱和拆箱會大大減低性能;
3)有些操做自己在並行流上的性能就比順序流差;
4)流的操做流水線的總計算成本;
5)對於較小的數據量,選擇並行流幾乎歷來都不是一個好的決定;
6)要考慮背後的數據結構是否易於分解;
7)流自身的特定,以及流水線中的中間操做修改流的方式,均可能會改變分解過程的性能;
8)考慮終端操做中合併步驟的代價是大是小;

Spliterator Java8的新接口,定義並行流如何拆分它要遍歷的數據。

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

##1.3 其餘 現代程序設計方法,改善代碼質量 ###重構、測試、調試 改善代碼的可讀性:
1)用Lambda表達式取代匿名類:在匿名類中this表明類自身,Lambda裏this表明包含類;匿名類能夠屏蔽包含類的同名變量,而Lambda表達式不能;
2)用方法引用重構Lambda表達式;
3)用Stream API重構命令式的數據處理;

增長代碼的靈活度: 1)採用函數接口;
2)有條件的延遲執行;
3)環繞執行;

Lambda表達式會使棧跟蹤的分析變得更爲複雜。流提供peek方法在分析Stream流水線時,能夠將中間變量的值輸出到日誌中,經常使用於調試代碼。

###default默認方法 Java8的接口能夠經過默認方法和靜態方法提供方法的代碼實現。經過默認方法能夠指定接口方法的默認實現,實現類若是不顯示提供該方法的具體實現,就會自動繼承默認的實現。這種機制能夠平滑地進行接口的優化和演進。默認方法的開頭以關鍵字default修飾,方法體與常規的類方法相同。

靜態方法及接口同時定義接口以及工具輔助類是Java語言經常使用的一種模式,工具類定義了接口實例協做的不少靜態方法。在有了默認方法後,這些輔助類就沒有存在的必要了,能夠把這些輔助類的靜態方法轉移到接口內部。

java8中抽象類和抽象接口:1)一個類只能繼承一個抽象類,可是一個類能夠實現多個接口;2)一個抽象類可要經過實例變量保存一個通用狀態,而接口是不能有實例變量的。

默認方法的使用模式:1)可選方法;2)行爲多繼承:類型的多繼承,利用正交方法的精簡接口,組合接口

解決衝突的規則 1)類中的方法優先級最高。類或父類中聲明的方法的優先級高於任何聲明默認方法的優先級;
2)若是沒法依據第一條進行判斷,那麼子接口的優先級更高:函數簽名相同時,優先級選擇擁有最具體實現的默認方法的接口,即若是B繼承了A,那麼B就比A更具體;
3)若是仍是沒法判斷,繼承了多個接口的淚必須經過顯示覆蓋和調用指望的方法,顯示地選擇使用哪個默認方法的實現(x.super.m(...))。
C++中的菱形問題更復雜:由於是類多繼承,除了方法的衝突還要考慮到變量的衝突。

###Optional 1)java8中引入了一個新的類java.util.Optional<T>對存在或缺失的變量值進行建模;
2)可使用靜態工廠方法Optional.empty,Optional.of以及Optional.ofNullable建立Optional對象。
3)Optional類支持多種方法:好比map, flatMap, filter,在概念上和Stream類類似;
4)null判斷,不用isPresent:

public static final Optional<Integer> max(Optional<Integer> i, Optional<Integer> j) {
     return i.flatMap(a -> j.map(b -> Math.max(a, b)));
}
public static int readDurationWithOptional(Properties props, String name) {
    return ofNullable(props.getProperty(name))
            .flatMap(ReadPositiveIntParam::s2i)
            .filter(i -> i > 0).orElse(0);
}

5)orElseGet(Supplier<? extends T> other)是orElse方法的延遲調用版,Supplier方法只有在Optional對象不含只時才調用。若是建立默認值是件耗時費力的工做,能夠考慮採用這種方式;
6)Optinal沒法序列化

###組合式異步編程CompletableFuture 執行比較耗時的操做時,尤爲是那些依賴一個或多個遠程服務的操做,使用異步任務能夠改善程序的性能,加快程序的響應速度。

對集合進行並行計算有2種方式:1)將其轉化爲並行流,利用map操做開展工做;2)枚舉出集合衆每個元素,建立新的線程,在CompletableFurture內對其進行操做。後者提供了更多地靈活性,能夠調整線程池的大小,進而確保總體的計算不會由於現場都在等待I/O而發生阻塞。

1)若是進行的實計算密集型的操做,而且沒有I/O,那麼就推薦使用Stream接口,由於實現簡單,同時效率也多是最高的(若是全部的線程都是計算密集型的,那就沒有必要建立比處理器核數更多的線程);
2)若是並行的工做單元還涉及等待I/O的操做,那麼使用CompletaleFuture靈活性更好,能夠根據Nthreads=Ncpu*Ucpu*(1+W/C)(Ncpu是處理器的核數,Ucpu是指望的CPU利用率,W/C是等待時間與計算時間的比率)設定須要使用的線程數。這種狀況不使用並行流的另外一個緣由:處理劉的流水線中若是發生I/O等待,流的延遲特性會讓咱們很難判斷究竟是何時觸發了等待。

###新Date和TIme接口
TemporalField, ChronoField
Temporal:定義如何讀取和操縱爲時間建模的對象的值;

LocalDate:不可變對象,提供簡單的日期,不含時間和時區信息
LocalTime:
LocalDateTIme:
Instant:便於機器使用,從1970-01-01開始經歷的秒數

間隔:
Duration:2個Temporal對象之間的duration
Period:以年、月、日的方式對多個時間單位建模 TemporalAdjuster:

格式化:
DateFormatter:

時區:
ZoneId:區時信息 ZoneDateTime:
ZoneOffset:
OffsetDateTime:

日曆系統: Chronology: ChronoLocalDate: ThaiBuddhistDate: MiguoDate: JapaneseDate: HijrahDate:

相關文章
相關標籤/搜索