亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java函數式編程(八):字符串及方法引用

2019-11-26 15:24:27
字體:
來源:轉載
供稿:網友

第三章 字符串,比較器和過濾器

JDK引入的一些方法對寫出函數式風格的代碼很有幫助。JDK庫里的一些的類和接口我們已經用得非常熟悉了,比如說String,為了擺脫以前習慣的那種老的風格,我們得主動尋找機會來使用這些新的方法。同樣,當我們需要用到只有一個方法的匿名內部類時,我們現在可以用lambda表達式來替換它了,不用再像原來那樣寫的那么繁瑣了。

本章我們會使用lambda表達式和方法引用來遍歷字符串,實現Comparator接口,查看目錄中的文件,監視文件及目錄的變更。上一章中介紹的一些方法還將繼續出現在這里,來幫助我們更好的完成這些任務。你學到的這些新技術有助于將冗長繁瑣的代碼變得簡潔,不僅能快速實現而且還易于維護。

遍歷字符串

chars()方法是String類里的一個新方法,它是CharSequence接口的一部分。想要快速遍歷String的字符序列的話,它是一個很有用的工具。有了這個內部迭代器,我們可以方便的操作字符串中的各個字符。先用它來處理一個字符串試試。在這里順便介紹方法引用的幾種使用方式。

復制代碼 代碼如下:

final String str = "w00t";
str.chars()
     .forEach(ch -> System.out.println(ch));

chars()方法返回的是一個Stream對象,我們可以用它的內部迭代器forEach()來進行遍歷。在迭代器里,我們可以直接訪問到字符串中的字符。下面是遍歷字符串并打印各個字符的輸出結果。
復制代碼 代碼如下:

119
48
48
116

這并不是我們想要的結果。我們希望看到的是字母,而輸出的卻是數字。這是因為chars()方法返回的是一個整型的Stream而不是字符型的。我們先了解下這個API,再去優化輸出的結果。

前面的代碼中我們創建了一個lambda表達式,作為forEach方法的入參。它只是簡單地把參數傳給了一個println()方法。由于這個操作很常見,我們可以借助Java編譯器來對這段代碼進行簡化。就像在25頁的使用方法引用中那樣,用一個方法引用來代替它,讓編譯器來幫我們做參數路由。

我們已經看到如何創建一個實例方法的方法引用了。比如,name.toUpperCase()方法,方法引用就是String::toUpperCase。而下面這個例子中,我們調用的是靜態引用System.out的一個實例方法。方法引用的兩個冒號左邊,可以是一個類名或者表達式。有了這個靈活性,我們可以很容易創建一個println()方法的引用,就像下面這樣。

復制代碼 代碼如下:

str.chars()
     .forEach(System.out::println);

可以看到,Java編譯器能很聰明的完成參數的路由。回想下lambda表達式和方法引用只能出現在接收函數式接口的地方,而Java編譯器會在那個地方生成一個對應的方法(譯注:編譯器會生成函數式接口的實現,這個實現只有一個方法)。之前我們用過的方法引用String::toUpperCase,傳給那個生成方法的參數,最后會變成這個方法調用的目標對象,就像這樣:parameter.toUpperCase()。這是因為這個方法引用是基于類名的(String)。而上面這個例子中的方法引用,是基于一個表達式的,它是PrintStream的一個實例,通過System.out來引用它。由于方法調用的對象已經有了,Java編譯器決定用生成方法中的參數作為這個println方法的參數:System.out.println(name)。

(譯注:其實主要是兩種場景,同樣是傳遞了一個方法引用,一個是把遍歷的對象,當然方法調用的目標對象,比如name.toUpperCase,另外一種是作為方法調用的參數,比如System.out.println(name).)

用了方法引用之后代碼簡潔多了,不過我們得去深入了解下它是如何運行的。一旦我們熟悉了方法引用,就能自己想明白參數路由這些事了。

盡管這個例子中的代碼已經夠簡潔的了,但是輸出還是不如人意。我們想看到的是字母結果卻出現了數字。為了解決這個問題,我們來寫個方法將int輸出成字母。

復制代碼 代碼如下:

private static void printChar(int aChar) {
      System.out.println((char)(aChar));
}

使用方法引用可以很方便的完成輸出結果的優化。
復制代碼 代碼如下:

str.chars()
     .forEach(IterateString::printChar);

現在雖然chars()返回的結果是int,但是也無所謂了,需要打印的時候,我們會將它轉化成字符。這回的輸出終于是字母了。
復制代碼 代碼如下:

w
0
0
t

如果我們希望從一開始就處理的就是字符而不是int,可以在調用完chars后直接將int轉化成字符:
復制代碼 代碼如下:

str.chars()
     .mapToObj(ch -> Character.valueOf((char)ch))
     .forEach(System.out::println);

這里我們用到了chars()返回的Stream的一個內部迭代器,當然能用的可不止這一個方法。拿到Stream對象后,它的那些方法就任憑我們使用了,比如map(),filter(),reduce()等。我們可以使用filter()方法來過濾出那些是數字的字符:
復制代碼 代碼如下:

str.chars()
     .filter(ch -> Character.isDigit(ch))
     .forEach(ch -> printChar(ch));

這樣輸出的時候我們就只能看到數字了:
復制代碼 代碼如下:

0
0

同樣的,除了將lambda表達式傳給filter()和forEach()方法外,我們還可以使用方法引用。
復制代碼 代碼如下:

str.chars()
     .filter(Character::isDigit)
     .forEach(IterateString::printChar);

這里的方法引用把多余的參數路由給省掉了。在本例中,我們還看到了和前面兩個方法的引用不同的用法。第一次我們引用的是一個實例方法,第二次是一個靜態引用(System.out)上的方法。而這次則是一個靜態方法的引用――方法引用一直在默默的付出。

實例方法和靜態方法的引用看起來都一樣:比方說String::toUpperCase和Character::isDigit。編譯器會判斷方法是實例方法還是靜態方法,來決定如何路由參數。如果是實例方法,它會將生成方法的入參用作方法調用的目標對象,比如 parameter,toUpperCase();(當然也有例外,比如方法調用的目標對象已經指定了,像System::out.println())。另外如果是靜態方法的話,生成方法的入參就會作為這個引用的方法的參數,比如Character.isDigit(parameter)。152頁的附錄2,有詳細的方法引用的使用方法及語法說明。

盡管方法引用用起來很方便,但還有一個問題――方法命名沖突導致的二義性 。如果匹配的方法既有實例方法也有靜態方法,由于方法存在歧義編譯器會報錯。比如這么寫,Double::toString,我們其實是想要把一個double類型轉化成字符串,但編譯器就不知道到底是該調用public String toString()的實例方法好,還是去調用public static String toString(double)方法,因為兩個方法都是Double類的。如果你碰到這樣的情況,別灰心,就用lambda表達式來完成就好了。

一旦我們適應了函數式編程,我們就可以在lambda表達式和方法引用之間隨心所欲地來回切換了。

本節中我們用了Java 8中的一個新方法來遍歷字符串。下面我們來看下Comparator接口又有了哪些改進。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
最新的欧美黄色| 亚洲一区二区三区成人在线视频精品| 欧美性一区二区三区| 欧美一级大胆视频| 国产亚洲人成a一在线v站| 国产精品免费看久久久香蕉| 2019中文在线观看| 亚洲国产天堂久久国产91| 尤物精品国产第一福利三区| 国产精品99蜜臀久久不卡二区| 97人人爽人人喊人人模波多| 亚洲欧美日韩中文视频| 成人免费xxxxx在线观看| 日本高清不卡在线| 日本道色综合久久影院| 久久久91精品国产一区不卡| 国产97在线|亚洲| 欧美床上激情在线观看| 亚洲网站在线观看| 欧美在线性爱视频| 日韩av手机在线看| 国产精品久久久久久久久久ktv| 日本精品中文字幕| 欧美电影免费观看网站| 中文字幕免费精品一区高清| 欧美成人国产va精品日本一级| 久久久久这里只有精品| 日韩免费在线电影| 亚洲91精品在线| 日韩激情视频在线播放| 国产亚洲欧美aaaa| 九九热这里只有精品免费看| 欧洲日本亚洲国产区| 日韩中文视频免费在线观看| 日韩电影免费观看在线观看| 久久男人资源视频| 国产91精品视频在线观看| 久久精品国产96久久久香蕉| 成人黄色av免费在线观看| 国产精品777| 日韩欧美第一页| 国产精品美女视频网站| 91欧美精品成人综合在线观看| 久久人人97超碰精品888| 日韩视频在线一区| 亚洲国产古装精品网站| 国产精品自产拍高潮在线观看| 91av在线精品| 欧美综合激情网| 国产日韩换脸av一区在线观看| 精品亚洲一区二区三区| 亚洲天堂成人在线| 日韩av免费网站| 亚洲成色777777女色窝| 欧美性猛交xxxx富婆弯腰| 亚洲国产成人爱av在线播放| 欧美一区二区三区艳史| 国产成人综合一区二区三区| 日韩av一区二区在线| 成人性生交xxxxx网站| 日韩av网站大全| 日韩av网站电影| 在线播放日韩专区| 亚洲男人天堂2019| 91免费精品视频| 欧美日韩中文字幕综合视频| 亚洲字幕一区二区| 福利视频第一区| 日韩欧美在线视频日韩欧美在线视频| 成人黄色激情网| 欧美精品日韩三级| 黑人巨大精品欧美一区二区一视频| 91在线高清免费观看| 欧美乱大交xxxxx另类电影| 亚洲人成啪啪网站| 久久久久北条麻妃免费看| 日本精品免费观看| 久久99精品久久久久久青青91| 国产精品久久久久久久久久| 久久99亚洲精品| 一个人看的www久久| 在线色欧美三级视频| 久久国产精品影视| 亚洲人成毛片在线播放| 欧美精品videos另类日本| 伊人伊人伊人久久| 91精品在线影院| 81精品国产乱码久久久久久| 国产一区二区三区在线视频| 欧美放荡办公室videos4k| 毛片精品免费在线观看| 国产精品日日摸夜夜添夜夜av| 亚洲精品国产suv| xvideos成人免费中文版| 国产有码在线一区二区视频| 亚洲aa中文字幕| 国产日韩欧美中文在线播放| 日韩av网站大全| 国产精品免费网站| 国产欧美精品一区二区三区介绍| 992tv在线成人免费观看| 成人激情av在线| 欧美乱妇高清无乱码| 亚洲图片欧美午夜| 国产精品成人av性教育| 欧美成人一区在线| 欧美在线视频观看| 亚洲欧美国产va在线影院| 国产成人aa精品一区在线播放| 日韩欧美第一页| 国产99视频在线观看| 97婷婷大伊香蕉精品视频| 狠狠操狠狠色综合网| 午夜精品一区二区三区在线| 欧美日韩国产一区二区三区| 亚洲成在人线av| 国产精品国产亚洲伊人久久| 综合网中文字幕| 亚洲国产99精品国自产| 欧美激情手机在线视频| 亚洲tv在线观看| 久久精品国产一区| 亚洲成人激情在线观看| 亚洲国产精品久久91精品| 亚洲人成亚洲人成在线观看| 日韩av一区二区在线观看| 亚洲品质视频自拍网| 日韩av电影手机在线| 久久国产精品久久精品| 亚洲区免费影片| 亚洲最大福利视频| 91香蕉嫩草影院入口| 97超碰国产精品女人人人爽| 日韩在线观看免费全集电视剧网站| 国产自产女人91一区在线观看| 久久精品最新地址| 日本亚洲欧美三级| 欧美电影第一页| 日本精品性网站在线观看| 中文字幕在线成人| 欧美日韩在线影院| 亚洲欧美国产精品va在线观看| 久久久久久国产三级电影| 日韩av日韩在线观看| 国产精品美女免费看| 欧美精品久久久久久久免费观看| 亚洲欧美色图片| 久久久久久久色| 欧美极品少妇与黑人| 日韩在线观看精品| 久久久久久噜噜噜久久久精品| 在线成人激情黄色| 91精品啪在线观看麻豆免费| 91av网站在线播放| 亚洲最大的免费| 日韩在线观看av| 欧美日韩免费在线| 91在线免费视频| 91在线高清免费观看| 欧美在线一级视频| 亚洲福利视频专区| 色播久久人人爽人人爽人人片视av| 欧美精品电影免费在线观看| 欧美视频在线观看 亚洲欧|