java8 新特性

java8 新特性

核心內(nèi)容

  • Lambda:函數(shù)式接口編程乌询,簡(jiǎn)化代碼量翔试,類(lèi)型上下文自動(dòng)推斷厦幅。
  • Stream Api:

1. Lambda 表達(dá)式

概念

java8引入面向函數(shù)編程舌缤,其中面向函數(shù)編程將函數(shù)作為參數(shù)傳遞瓣距,由于java是基于對(duì)象的黔帕,不存在單獨(dú)的函數(shù)。因此java8取巧蹈丸,采用單內(nèi)部函數(shù)的接口作為函數(shù)參數(shù)成黄,實(shí)習(xí)了傳遞函數(shù)的功能呐芥。Lambda表達(dá)式即實(shí)現(xiàn)了以上功能。

語(yǔ)法

lambda表達(dá)式的語(yǔ)法:由參數(shù)列表奋岁、箭頭符號(hào)->和函數(shù)體組成思瘟。如:

// 單句函數(shù)體無(wú)需{}
Runnable r1 = () -> System.out.println("無(wú)參數(shù)的lambda表達(dá)式");
r1.run();

// 單輸入?yún)?shù)可以省略
Consumer<String> c1 = (name) -> System.out.println("我的大名是"+name);
Consumer<String> c2 = name -> System.out.println("我的大名是"+name);
c1.accept("zhangjue");
c2.accept("張玨");

// 單語(yǔ)句return可以省略
Supplier<String> s1 = () -> "張玨教你學(xué)lambda";
System.out.println(s1.get());

// 范性中不支持基本類(lèi)型
//Function< String, int> f1 = name -> return (Integer)18;
Function< String, Integer> f1 = name -> {
    return 18;
};
System.out.println("張玨今年"+f1.apply("zhangjue")+"歲");

// {}最后記得加;
Predicate<String> p1 = name -> {
    if( "張玨".equals(name))
    {
        return true;
    }
    else
    {
        return false;
    }
};

if(p1.test("zy")){
    System.out.println("找到了大神");
}
else {
    System.out.println("可能是菜雞");
}
函數(shù)式接口
  • 只包含一個(gè)抽象方法的接口,稱(chēng)為函數(shù)式接口
  • @FunctionalInterface: 檢驗(yàn)是否符號(hào)函數(shù)式接口要求
  • java.util.function包:它里面包含了常用的函數(shù)式接口

給定的lambda表達(dá)式闻伶,它的類(lèi)型是由其上下文推導(dǎo)而來(lái)滨攻。這意味著同樣的lambda表達(dá)式在不同上下文里可以擁有不同的類(lèi)型。這也是為什么lambda表達(dá)式中的參數(shù)不用寫(xiě)類(lèi)型的原因蓝翰。

例如:

Callable c =()->"done";         //Callable類(lèi)型
PrivilegedAction a =()->"done"; //PrivilegedAction類(lèi)型

目標(biāo)類(lèi)型 T 需要滿足的條件:

  • lambda表達(dá)式的參數(shù)和T的方法參數(shù)在數(shù)量和類(lèi)型上一一對(duì)應(yīng)
  • lambda表達(dá)式的返回值和T的方法返回值相兼容
  • lambda表達(dá)式內(nèi)所拋出的異常和T的方法throws類(lèi)型相兼容

3. 方法引用與構(gòu)造器引用

使用現(xiàn)成的方法或者構(gòu)造器代替lambda表達(dá)式光绕。具體方式有以下幾種。

方法引用
  1. 實(shí)例對(duì)象::實(shí)例方法名
  2. 類(lèi)名::靜態(tài)方法名
  3. 類(lèi)名::實(shí)例方法名
構(gòu)造器引用
  1. 類(lèi)名::new
  2. 類(lèi)型[]::new

代碼:

String str = "zhangjue";
Float f = 3.14f;

//  實(shí)例對(duì)象::實(shí)例方法名畜份,沒(méi)有參數(shù)  
//Supplier<String> sup = () -> str.toUpperCase();
Supplier<String> sup = str::toUpperCase;
System.out.println(sup.get());

//  實(shí)例對(duì)象::實(shí)例方法名诞帐,有參數(shù)。
//Consumer con = (x) -> System.out.println(x);
Consumer<String> con = System.out::println; // 不指定參數(shù)
con.accept(str);            //自動(dòng)指定參數(shù)


//類(lèi)名::靜態(tài)方法名爆雹。參數(shù)和上面的一樣停蕉。
//Function<Float, Integer> fun = (x) -> Math.round(x);
Function<Float, Integer> fun = Math::round;
System.out.println(fun.apply(f));

//實(shí)例對(duì)象::方法名。參數(shù)和上面的一樣钙态。必須非靜態(tài)方法慧起。
//Consumer<Client> cli = (x) -> x.say();
Consumer<Client> cli = Client::sayHello;
cli.accept(new Client());

// 類(lèi)名::new  
//Function<String, StringBuffer> funConstruct = (x) -> new StringBuffer(x);
Function<String, StringBuffer> funConstruct = StringBuffer::new;

// 類(lèi)型[]::new
//Function<Integer, String[]> funString = (e) -> new String[e];
Function<Integer, String[]> funString = String[]::new;
String[] strArray = funString.apply(7);

4. Stream API

位于java.util.stream包:

Stream 是 Java8 提供一種處理數(shù)據(jù)的方式,多個(gè)中間操作可以連接起來(lái)形成一個(gè)流水操作驯绎,直到遇到終止操作時(shí)才一次性全部執(zhí)行完慧,稱(chēng)為“惰性求值”。

Stream API的并發(fā)采用的是我們熟悉的fork/join模式剩失,采用Stream API來(lái)進(jìn)行集合對(duì)象上的并發(fā)操作不需要編寫(xiě)多線程代碼屈尼,也極大的簡(jiǎn)化了編程難度。Stream API 可以聲明性地通過(guò) parallel() 與 sequential() 在并行流與順序流之間進(jìn)行切換拴孤。

特點(diǎn)
  1. Stream 自己不會(huì)存儲(chǔ)元素脾歧。
  2. Stream 不會(huì)改變?cè)磳?duì)象。相反演熟,他們會(huì)返回一個(gè)持有結(jié)果的新Stream鞭执。
  3. Stream 操作是延遲執(zhí)行的。這意味著他們會(huì)等到需要結(jié)果的時(shí)候才執(zhí)行

使用一個(gè)Stream的步驟分為:創(chuàng)建芒粹、中間操作兄纺、終止操作。

創(chuàng)建 Stream
  1. Collection 接口被擴(kuò)展化漆,提供了兩個(gè)獲取流的方法:

    • default Stream<E> stream() : 返回一個(gè)順序流

    • default Stream<E> parallelStream() : 返回一個(gè)并行流

        ArrayList<User> users = new ArrayList<>();
        Stream<User> stream = users.stream();
        Stream<User> stream = users. parallelStream();
      
  2. Arrays 的靜態(tài)方法 stream() 可 以獲取數(shù)組流

    重載類(lèi)型
    • public static IntStream stream(int[] array)
    • public static LongStream stream(long[] array)
    • public static DoubleStream stream(double[] array)
  3. Stream.of(), 通過(guò)顯示值 創(chuàng)建一個(gè)流估脆。它可以接收任意數(shù)量的參數(shù)。

     String[] str = {"Hello World", "Hello Java", "Hello Steam"};
     Stream<String> stream = Stream.of(str);
     Stream<Integer> stream = Stream.of(1, 2, 3, 4);
    
  4. Stream.iterate() 和 Stream.generate(), 創(chuàng)建無(wú)限流座云。

中間操作

篩選與切片:

映射:

排序:

終止操作(終端操作)

查找與匹配:

歸約:

map 和 reduce 的連接通常稱(chēng)為 map-reduce 模式疙赠,被google所采用付材。

收集:

收集操作的靜態(tài)方法

注:一個(gè)流只能執(zhí)行一個(gè)結(jié)束操作,當(dāng)執(zhí)行了結(jié)束操作以后這個(gè)流就不能再被執(zhí)行圃阳,也就是說(shuō)不能再次進(jìn)行中間操作或結(jié)束操作厌衔,所以結(jié)束操作一定是流的最后一個(gè)操作。

5. 接口中的默認(rèn)方法與靜態(tài)方法

Java 8中允許接口中包含具有具體實(shí)現(xiàn)的方法捍岳,該方法稱(chēng)為 “默認(rèn)方法”富寿,默認(rèn)方法使用 default 關(guān)鍵字修飾。

接口中允許添加靜態(tài)方法祟同。
默認(rèn)方法的”類(lèi)優(yōu)先”原則:
  • 接口中定義了一個(gè)默認(rèn)方法作喘,父類(lèi)定義了一個(gè)同名的方法時(shí)選擇父類(lèi)中的方法理疙。

  • 接口沖突:父接口提供一個(gè)默認(rèn)方法晕城,另一個(gè)接口也提供了一個(gè)具有相同名稱(chēng)和參數(shù)列表的方法(不管方法是否是默認(rèn)方法),那么必須覆蓋該方法來(lái)解決沖突窖贤。

6. Optional 類(lèi)

java.util.Optional包內(nèi)砖顷。是一個(gè)容器類(lèi),代表一個(gè)值存在或不存在赃梧,原來(lái)用 null 表示一個(gè)值不存在滤蝠,現(xiàn)在 Optional 可以避免空指針異常。

常用方法
Optional.of(T t)    //創(chuàng)建一個(gè) Optional 實(shí)例
Optional.empty()    //創(chuàng)建一個(gè)空的 Optional 實(shí)例
Optional.ofNullable(T t)    //若 t 不為 null,創(chuàng)建 Optional 實(shí)例,否則創(chuàng)建空實(shí)例 isPresent()    //判斷是否包含值
orElse(T t)     //如果調(diào)用對(duì)象包含值授嘀,返回該值物咳,否則返回t
orElseGet(Supplier s)   //如果調(diào)用對(duì)象包含值,返回該值蹄皱,否則返回 s 獲取的值 
map(Function f)  //如果有值對(duì)其處理览闰,并返回處理后的Optional,否則返回 Optional.empty() 
flatMap(Function mapper)    //與 map 類(lèi)似巷折,要求返回值必須是Optional

7. Fork/Join 框架

將一個(gè)大任務(wù)压鉴,進(jìn)行拆分(fork)成若干個(gè) 小任務(wù)(拆到不可再拆時(shí)),再將一個(gè)個(gè)的小任務(wù)運(yùn)算的結(jié)果進(jìn)行 join 匯總

采用 “工作竊取”模式:

在一般的線程池中,如果一個(gè)線程正在執(zhí)行的任務(wù)由于某些原因 無(wú)法繼續(xù)運(yùn)行,那么該線程會(huì)處于等待狀態(tài).而在fork/join框架實(shí)現(xiàn)中,如果 某個(gè)子問(wèn)題由于等待另外一個(gè)子問(wèn)題的完成而無(wú)法繼續(xù)運(yùn)行.那么處理該子 問(wèn)題的線程會(huì)主動(dòng)尋找其他尚未運(yùn)行的子問(wèn)題來(lái)執(zhí)行.這種方式減少了線程 的等待時(shí)間,提高了性能.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锻拘,一起剝皮案震驚了整個(gè)濱河市油吭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌署拟,老刑警劉巖婉宰,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異推穷,居然都是意外死亡心包,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)缨恒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谴咸,“玉大人轮听,你說(shuō)我怎么就攤上這事×爰眩” “怎么了血巍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)珊随。 經(jīng)常有香客問(wèn)我述寡,道長(zhǎng),這世上最難降的妖魔是什么叶洞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任鲫凶,我火速辦了婚禮,結(jié)果婚禮上衩辟,老公的妹妹穿的比我還像新娘螟炫。我一直安慰自己,他們只是感情好艺晴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布昼钻。 她就那樣靜靜地躺著,像睡著了一般封寞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狈究,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音亿眠,去河邊找鬼。 笑死宁改,一個(gè)胖子當(dāng)著我的面吹牛缕探,可吹牛的內(nèi)容都是我干的还蹲。 我是一名探鬼主播爹耗,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼谜喊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼潭兽!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起斗遏,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诵次,沒(méi)想到半個(gè)月后枚碗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體铸本,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年怨规,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片波丰。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舶得,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出扩灯,到底是詐尸還是另有隱情霜瘪,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布颖对,位于F島的核電站,受9級(jí)特大地震影響顾患,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜江解,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一徙歼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧魄梯,春花似錦、人聲如沸酿秸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至读处,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間罚舱,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工管闷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窃肠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓冤留,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親糯而。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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

  • java8新特性 原創(chuàng)者:文思 一熄驼、特性簡(jiǎn)介 速度更快 代碼更少烘豹,增加了Lambda 強(qiáng)大的Stream API ...
    文思li閱讀 3,047評(píng)論 1 1
  • 對(duì)于Java開(kāi)發(fā)者來(lái)說(shuō),Java8的版本顯然是一個(gè)具有里程碑意義的版本祭芦,蘊(yùn)含了許多令人激動(dòng)的新特性,如果能利用好這...
    jackcooper閱讀 1,025評(píng)論 0 6
  • Java8新特性 Lambda表達(dá)式 概念 lambda表達(dá)式是一段可以傳遞的代碼龟劲,它的核心思想是將面向?qū)ο笾械膫?..
    好好秦先生閱讀 836評(píng)論 0 1
  • 最堅(jiān)強(qiáng)的堅(jiān)強(qiáng)逊彭,是心里再苦再累也要若無(wú)其事地笑著。 只有自己才能拯救自己侮叮,佛主菩薩早已告訴你。
    安靜世界閱讀 183評(píng)論 0 0
  • 有一只飛蛾的理想是變成蒼鷹在高空飛翔审胸,于是亥宿,他每天都照著蒼鷹飛翔的姿勢(shì)砂沛,反復(fù)練習(xí)。不過(guò)碍庵,他飛得依然是那么高,甚至比...
    常非常K閱讀 315評(píng)論 0 3