Java 8 特性

原文鏈接
非常簡單地整理了一下Java 8 中出現(xiàn)的新特性,Lambda 部分的例子借鑒了這里 度硝。

Lambda 表達式

Java 8 中最大特性,函數(shù)式編程

語法

Lambda 表達式:

parameter -> expression body
  1. 可選參數(shù)類型聲明 - 不需要聲明參數(shù)類型寿冕,編譯器可以自動推斷
  2. 可選小括號 - 只有一個參數(shù)時可以省略左側(cè)的括號蕊程,多參數(shù)時小括號是必須的
  3. 可選大括號 - 當(dāng)函數(shù)體只有一條語句時可以省略大括號
  4. 可選return關(guān)鍵字 - 函數(shù)體只有一條語句時,編譯器會自動返回結(jié)果

字符串排序 pre Java 8 實現(xiàn):

List<String> strings = Arrays.asList("ab", "a", "bd", "bc", "c", "ca");
Collections.sort(strings, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});
System.out.println(strings);

out : [a, ab, bc, bd, c, ca]

如果用 Lambda 表達式:

List<String> stringsLambda = Arrays.asList("ab", "a", "bd", "bc", "c", "ca");
Collections.sort(stringsLambda, (a, b) -> a.compareTo(b));
System.out.println(stringsLambda);

可選參數(shù)類型聲明:(a, b) 等價于 (String a, String b)
可選小括號:此處有兩個參數(shù)驼唱,不可省略
可選大括號藻茂、return關(guān)鍵字:a.compareTo(b) 等價于 {return a.compareTo(b);}

Lambda 范圍

可以使用 final 類型的變量

public class Java8Tester {
    final static String salutation = "Hello! ";

    public static void main(String args[]) {
        GreetingService greetService1 = message -> System.out.println(salutation + message);
        greetService1.sayMessage("Mahesh");
    }

    interface GreetingService {
        void sayMessage(String message);
    }
}

Method references

Method references 可以通過名稱指向方法,使用符號 ::玫恳,可以指向:

  1. 靜態(tài)方法
  2. 實例方法
  3. 使用operator的構(gòu)造函數(shù) TreeSet::new
List names = new ArrayList();
names.add("Alice");
names.add("Bob");
names.add("Chirs");
names.forEach(System.out::println);

out:
Alice
Bob
Chris

Functional interfaces

Functional interfaces 具有單一功能辨赐,舉例來說 Comparable 接口僅僅有一個用于比較大小的方法CompareTo , Java 8 中定義了很多 Functional interfaces,以便在 lambda表達式 中廣泛使用京办。

Predicate <T> 是一個包含一個方法test(Object)的實用接口掀序,這個方法返回一個布爾值,用來表示傳入對象的測試結(jié)果是 true 或 false惭婿。

public static void eval(List<Integer> list, Predicate<Integer> predicate) {
    for(Integer n: list) {
        if(predicate.test(n)) {
            System.out.print(n + " ");
        }
    }
    System.out.println();
}

測試一下:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
System.out.println("Print all numbers:");
eval(list, n->true);
System.out.println("Print even numbers:");
eval(list, n-> n%2 == 0 );
System.out.println("Print numbers greater than 3:");
eval(list, n-> n > 3 );

out :
Print all numbers:
1 2 3 4 5 6 7 8 9
Print even numbers:
2 4 6 8
Print numbers greater than 3:
4 5 6 7 8 9

Default Methods

Default Methods不恭,可以讓原有接口使用 Lambda 表達式。
比如财饥,ListCollection接口都沒有聲明 forEach方法换吧,強行加上這類方法又會破壞集合原有的實現(xiàn)框架。

語法

public interface vehicle {
   default void print() {
      System.out.println("I am a vehicle!");
   }
}

Multiple Defaults

當(dāng)接口中有 default 函數(shù)時钥星,有可能一個類實現(xiàn)了2個接口式散,而這2個接口中包含了同名的 default 函數(shù)

public interface vehicle {
   default void print() {
      System.out.println("I am a vehicle!");
   }
}

public interface fourWheeler {
   default void print() {
      System.out.println("I am a four wheeler!");
   }
}

第一種解決辦法:方法重寫

public class car implements vehicle, fourWheeler {
   default void print() {
      System.out.println("I am a four wheeler car vehicle!");
   }
}

第二種解決辦法:通過super調(diào)用特定接口的default方法

public class car implements vehicle, fourWheeler {
   default void print() {
      vehicle.super.print();
   }
}

Static Default Methods

接口同時可以擁有靜態(tài)函數(shù)

public interface vehicle {
   default void print() {
      System.out.println("I am a vehicle!");
   }

   static void blowHorn() {
      System.out.println("Blowing horn!!!");
   }
}

Stream

Stream 是一個抽象層的東西,使用Stream可以像SQL語句那樣操作數(shù)據(jù)(Stream 并不能處理SQL語句):

SELECT max(salary), employee_id FROM Employee

上面的SQL語句可以直接返回最高工資員工的工資和ID打颤,而使用 Collections 集合框架暴拄,則必須遍歷和多次check才能查找出上面的信息。
Stream 的另一個好處就是高效编饺,為避免并發(fā)下容易產(chǎn)生的錯誤乖篷,Java 8 中引入 Stream 的概念,讓我們可以直接使用多核系統(tǒng)而不用考慮具體的代碼實現(xiàn)透且。

Stream 表示一系列來自Source的對象

  1. 元素序列 - Stream 提供一個元素的集合撕蔼,其中的元素連續(xù)排列,且類型確定秽誊。
  2. 源Source - Stream 可以把集合類鲸沮、Arrays、I/O源當(dāng)做源锅论。
  3. Aggregate operations - Stream 支持集合運算:filter讼溺、map、limit最易、reduce怒坯、find、match等等
  4. Pipelining - 多數(shù) stream 操作返回 stream 本身藻懒,所以其操作結(jié)果可以用流水線的方式處理剔猿。這些操作可以叫 intermediate operations,它們接收輸入嬉荆、處理归敬、并將結(jié)果返回。collect() 操作是一個末端操作鄙早,通常在 pipelining 操作結(jié)束時出現(xiàn)以標(biāo)記流的結(jié)束汪茧。
  5. 自動迭代 - 在源元素內(nèi)部遍歷,與需要顯示迭代的集合類不同蝶锋。

生成 Stream

Collection 接口有兩個方法生成 Stream

  • stream() 返回一個將當(dāng)前集合內(nèi)容作為源的 sequential stream
  • parallelStream() 返回一個將當(dāng)前集合內(nèi)容作為源的 parallel Stream

Collectors

一個 Stream 經(jīng)過流操作之后還是 Stream 對象陆爽,可以通過 Collectors 將流處理的結(jié)果轉(zhuǎn)換為ListString。下面例子中生成Stream對象扳缕,沒有做任何流操作慌闭,再將其轉(zhuǎn)換為List,故filteredstrings內(nèi)容一致躯舔。

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().collect(Collectors.toList());

另外驴剔,Collectors也可以將不同流操作的結(jié)果合并起來。

String mergedString = strings.stream().collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);
//out : Merged String: abc, , bc, efg, abcd, , jkl

map

把每一個元素映射為相應(yīng)的結(jié)果粥庄。下面例子中將數(shù)字映射為其平方丧失,并打印不重復(fù)的值

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> squaresList = numbers.stream()
    .map( i -> i*i)
    .distinct()
    .collect(Collectors.toList());
System.out.println(squaresList); // [9, 4, 49, 25]

filter

濾除不符合條件 (保留符合條件)的元素,filter(paramters -> condition)

limit

限制Stream的大小惜互,limit(5) 流中元素不夠5個時不報錯布讹,取當(dāng)前所有元素琳拭。

sorted

排序

將濾除空字符串,取前5個元素描验,并排序:

List<String> strings = Arrays.asList("123", "", "456", " ", "78", "", "9");
List<String> result = strings.stream()
    .filter(str -> !str.isEmpty())
    .limit(5)
    .sorted()
    .collect(Collectors.toList());
System.out.println(result);   //[ , 123, 456, 78, 9]

forEach

Stream 提供了遍歷元素的新方法forEach白嘁,通過它打印10個隨機數(shù):

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

random.ints() 會返回一個 Stream對象

并行處理

做并行處理時可選用 parallelStream

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
int count = strings.parallelStream().filter(string -> string.isEmpty()).count();

統(tǒng)計計算

流處理結(jié)束后,可以計算統(tǒng)計數(shù)據(jù)

List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);
IntSummaryStatistics stats = integers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest number in List : " + stats.getMax());
System.out.println("Lowest number in List : " + stats.getMin());
System.out.println("Sum of all numbers : " + stats.getSum());
System.out.println("Average of all numbers : " + stats.getAverage());

out:
Highest number in List : 19
Lowest number in List : 1
Sum of all numbers : 85
Average of all numbers : 9.444444444444445

Optional Class

Optional 是一個包含非null對象的容器膘流, Optional 對象用值的缺失來表示null絮缅。
Optional 類有很多實用方法,可以將一個值處理為可用或不可用狀態(tài)呼股,從而不用進行是否為空值的檢查耕魄。類似于Guava中的Optional。

java.util.Optional 定義如下:

public final class Optional<T> extends Object

案例:

import java.util.Optional;

public class OptionalTest {
    public static void main(String[] args){
        OptionalTest optionalTest = new OptionalTest();
        Integer value1 = null;
        Integer value2 = new Integer(10);
        Optional<Integer> a = Optional.ofNullable(value1);
        Optional<Integer> b = Optional.of(value2);
        System.out.println(optionalTest.sum(a,b));
    }

    private Integer sum(Optional<Integer> a, Optional<Integer> b) {
        System.out.println("First parameter is present: " + a.isPresent());
        System.out.println("Second parameter is present: " + b.isPresent());
        Integer value1 = a.orElse(new Integer(0));
        Integer value2 = b.get();
        return value1 + value2;
    }
}

out:
First parameter is present: false
Second parameter is present: true
10

新的 Date/Time API

原有時間API

  1. 線程不安全
    java.util.Date 線程不安全彭谁,新的時間API是不可變的吸奴,且沒有setter方法
  2. 設(shè)計糟糕
    原有時間API起始1900,月份從1開始马靠,日期從0開始奄抽,沒有一致性。新API中提供了很多實用的方法甩鳄。
  3. 時區(qū)處理復(fù)雜

java.time

  • Local 簡化的 date-time API
  • Zoned 專門處理多時區(qū)的 date-time API

LocalDateTime 逞度、LocalDateLocalTime

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
System.out.println(localDateTime.getDayOfMonth());

LocalDate localDate = localDateTime.toLocalDate().withMonth(2);
System.out.println(localDate);

LocalDate date = LocalDate.of(1978, Month.SEPTEMBER, 21);
System.out.println(date);
LocalTime time = LocalTime.of(22, 15);
System.out.println(time);

LocalTime time2 = LocalTime.parse("20:15:30");

更多內(nèi)容詳見 [更多內(nèi)容詳見 Java8 Tutorial 妙啃。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末档泽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子揖赴,更是在濱河造成了極大的恐慌馆匿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燥滑,死亡現(xiàn)場離奇詭異渐北,居然都是意外死亡,警方通過查閱死者的電腦和手機铭拧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門赃蛛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搀菩,你說我怎么就攤上這事呕臂。” “怎么了肪跋?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵歧蒋,是天一觀的道長。 經(jīng)常有香客問我,道長谜洽,這世上最難降的妖魔是什么萝映? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮阐虚,結(jié)果婚禮上锌俱,老公的妹妹穿的比我還像新娘。我一直安慰自己敌呈,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布造寝。 她就那樣靜靜地躺著磕洪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诫龙。 梳的紋絲不亂的頭發(fā)上析显,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音签赃,去河邊找鬼谷异。 笑死,一個胖子當(dāng)著我的面吹牛锦聊,可吹牛的內(nèi)容都是我干的歹嘹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼孔庭,長吁一口氣:“原來是場噩夢啊……” “哼尺上!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起圆到,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤怎抛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芽淡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體马绝,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年挣菲,在試婚紗的時候發(fā)現(xiàn)自己被綠了富稻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡己单,死狀恐怖唉窃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纹笼,我是刑警寧澤纹份,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響蔓涧,放射性物質(zhì)發(fā)生泄漏件已。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一元暴、第九天 我趴在偏房一處隱蔽的房頂上張望篷扩。 院中可真熱鬧,春花似錦茉盏、人聲如沸鉴未。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铜秆。三九已至,卻和暖如春讶迁,著一層夾襖步出監(jiān)牢的瞬間连茧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工巍糯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留啸驯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓祟峦,卻偏偏與公主長得像罚斗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子搀愧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理惰聂,服務(wù)發(fā)現(xiàn),斷路器咱筛,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 第一章 為什么要關(guān)心Java 8 使用Stream庫來選擇最佳低級執(zhí)行機制可以避免使用Synchronized(同...
    謝隨安閱讀 1,491評論 0 4
  • JDK各個版本的新特性 對于很多剛接觸java語言的學(xué)者來說搓幌,要了解一門語言,最好的方式是從基礎(chǔ)的版本進行理解迅箩,升...
    小莊bb閱讀 1,098評論 0 1
  • ”談錢多俗啊,來來來奕塑,我們只談感情不談錢“看似沒毛病的一句話堂污,到底坑了多少礙于面子不談錢的人啊龄砰! A 林安有一個要...
    馬麗_106b閱讀 574評論 0 0
  • 蝶夢 文/姜彥偉 隔岸相望 夕陽隱去最后一抹嫣紅 水 披上夜的衣裳 暮色幽幽 散落一地琳瑯 方亭曉月 微風(fēng)拂...
    姜彥偉閱讀 364評論 2 1