成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 8 API 示例:字符串、數(shù)值、算術(shù)和文件

KavenFan / 1619人閱讀

摘要:示例字符串?dāng)?shù)值算術(shù)和文件原文譯者飛龍協(xié)議大量的教程和文章都涉及到中最重要的改變,例如表達(dá)式和函數(shù)式數(shù)據(jù)流。不僅僅是字符串,正則表達(dá)式模式串也能受益于數(shù)據(jù)流。

Java 8 API 示例:字符串、數(shù)值、算術(shù)和文件

原文:Java 8 API by Example: Strings, Numbers, Math and Files

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

大量的教程和文章都涉及到Java8中最重要的改變,例如lambda表達(dá)式和函數(shù)式數(shù)據(jù)流。但是此外許多現(xiàn)存的類在JDK 8 API中也有所改進(jìn),帶有一些實(shí)用的特性和方法。

這篇教程涉及到Java 8 API中的那些小修改 -- 每個(gè)都使用簡(jiǎn)單易懂的代碼示例來(lái)描述。讓我們好好看一看字符串、數(shù)值、算術(shù)和文件。

處理字符串

兩個(gè)新的方法可在字符串類上使用:joinchars。第一個(gè)方法使用指定的分隔符,將任何數(shù)量的字符串連接為一個(gè)字符串。

String.join(":", "foobar", "foo", "bar");
// => foobar:foo:bar

第二個(gè)方法chars從字符串所有字符創(chuàng)建數(shù)據(jù)流,所以你可以在這些字符上使用流式操作。

"foobar:foo:bar"
    .chars()
    .distinct()
    .mapToObj(c -> String.valueOf((char)c))
    .sorted()
    .collect(Collectors.joining());
// => :abfor

不僅僅是字符串,正則表達(dá)式模式串也能受益于數(shù)據(jù)流。我們可以分割任何模式串,并創(chuàng)建數(shù)據(jù)流來(lái)處理它們,而不是將字符串分割為單個(gè)字符的數(shù)據(jù)流,像下面這樣:

Pattern.compile(":")
    .splitAsStream("foobar:foo:bar")
    .filter(s -> s.contains("bar"))
    .sorted()
    .collect(Collectors.joining(":"));
// => bar:foobar

此外,正則模式串可以轉(zhuǎn)換為謂詞。這些謂詞可以像下面那樣用于過(guò)濾字符串流:

Pattern pattern = Pattern.compile(".*@gmail.com");
Stream.of("[email protected]", "[email protected]")
    .filter(pattern.asPredicate())
    .count();
// => 1

上面的模式串接受任何以@gmail.com結(jié)尾的字符串,并且之后用作Java8的Predicate來(lái)過(guò)濾電子郵件地址流。

處理數(shù)值

Java8添加了對(duì)無(wú)符號(hào)數(shù)的額外支持。Java中的數(shù)值總是有符號(hào)的,例如,讓我們來(lái)觀察Integer

int可表示最多2 ** 32個(gè)數(shù)。Java中的數(shù)值默認(rèn)為有符號(hào)的,所以最后一個(gè)二進(jìn)制數(shù)字表示符號(hào)(0為正數(shù),1為負(fù)數(shù))。所以從十進(jìn)制的0開始,最大的有符號(hào)正整數(shù)為2 ** 31 - 1。

你可以通過(guò)Integer.MAX_VALUE來(lái)訪問(wèn)它:

System.out.println(Integer.MAX_VALUE);      // 2147483647
System.out.println(Integer.MAX_VALUE + 1);  // -2147483648

Java8添加了解析無(wú)符號(hào)整數(shù)的支持,讓我們看看它如何工作:

long maxUnsignedInt = (1l << 32) - 1;
String string = String.valueOf(maxUnsignedInt);
int unsignedInt = Integer.parseUnsignedInt(string, 10);
String string2 = Integer.toUnsignedString(unsignedInt, 10);

就像你看到的那樣,現(xiàn)在可以將最大的無(wú)符號(hào)數(shù)2 ** 32 - 1解析為整數(shù)。而且你也可以將這個(gè)數(shù)值轉(zhuǎn)換回?zé)o符號(hào)數(shù)的字符串表示。

這在之前不可能使用parseInt完成,就像這個(gè)例子展示的那樣:

try {
    Integer.parseInt(string, 10);
}
catch (NumberFormatException e) {
    System.err.println("could not parse signed int of " + maxUnsignedInt);
}

這個(gè)數(shù)值不可解析為有符號(hào)整數(shù),因?yàn)樗隽俗畲蠓秶?b>2 ** 31 - 1。

算術(shù)運(yùn)算

Math工具類新增了一些方法來(lái)處理數(shù)值溢出。這是什么意思呢?我們已經(jīng)看到了所有數(shù)值類型都有最大值。所以當(dāng)算術(shù)運(yùn)算的結(jié)果不能被它的大小裝下時(shí),會(huì)發(fā)生什么呢?

System.out.println(Integer.MAX_VALUE);      // 2147483647
System.out.println(Integer.MAX_VALUE + 1);  // -2147483648

就像你看到的那樣,發(fā)生了整數(shù)溢出,這通常是我們不愿意看到的。

Java8添加了嚴(yán)格數(shù)學(xué)運(yùn)算的支持來(lái)解決這個(gè)問(wèn)題。Math擴(kuò)展了一些方法,它們?nèi)恳?b>exact結(jié)尾,例如addExact。當(dāng)運(yùn)算結(jié)果不能被數(shù)值類型裝下時(shí),這些方法通過(guò)拋出ArithmeticException異常來(lái)合理地處理溢出。

try {
    Math.addExact(Integer.MAX_VALUE, 1);
}
catch (ArithmeticException e) {
    System.err.println(e.getMessage());
    // => integer overflow
}

當(dāng)嘗試通過(guò)toIntExact將長(zhǎng)整數(shù)轉(zhuǎn)換為整數(shù)時(shí),可能會(huì)拋出同樣的異常:

try {
    Math.toIntExact(Long.MAX_VALUE);
}
catch (ArithmeticException e) {
    System.err.println(e.getMessage());
    // => integer overflow
}
處理文件

Files工具類首次在Java7中引入,作為NIO的一部分。JDK8 API添加了一些額外的方法,它們可以將文件用于函數(shù)式數(shù)據(jù)流。讓我們深入探索一些代碼示例。

列出文件

Files.list方法將指定目錄的所有路徑轉(zhuǎn)換為數(shù)據(jù)流,便于我們?cè)谖募到y(tǒng)的內(nèi)容上使用類似filtersorted的流操作。

try (Stream stream = Files.list(Paths.get(""))) {
    String joined = stream
        .map(String::valueOf)
        .filter(path -> !path.startsWith("."))
        .sorted()
        .collect(Collectors.joining("; "));
    System.out.println("List: " + joined);
}

上面的例子列出了當(dāng)前工作目錄的所有文件,之后將每個(gè)路徑都映射為它的字符串表示。之后結(jié)果被過(guò)濾、排序,最后連接為一個(gè)字符串。如果你還不熟悉函數(shù)式數(shù)據(jù)流,你應(yīng)該閱讀我的Java8數(shù)據(jù)流教程。

你可能已經(jīng)注意到,數(shù)據(jù)流的創(chuàng)建包裝在try-with語(yǔ)句中。數(shù)據(jù)流實(shí)現(xiàn)了AutoCloseable,并且這里我們需要顯式關(guān)閉數(shù)據(jù)流,因?yàn)樗贗O操作。

返回的數(shù)據(jù)流是DirectoryStream的封裝。如果需要及時(shí)處理文件資源,就應(yīng)該使用try-with結(jié)構(gòu)來(lái)確保在流式操作完成后,數(shù)據(jù)流的close方法被調(diào)用。

查找文件

下面的例子演示了如何查找在目錄及其子目錄下的文件:

Path start = Paths.get("");
int maxDepth = 5;
try (Stream stream = Files.find(start, maxDepth, (path, attr) ->
        String.valueOf(path).endsWith(".js"))) {
    String joined = stream
        .sorted()
        .map(String::valueOf)
        .collect(Collectors.joining("; "));
    System.out.println("Found: " + joined);
}

find方法接受三個(gè)參數(shù):目錄路徑start是起始點(diǎn),maxDepth定義了最大搜索深度。第三個(gè)參數(shù)是一個(gè)匹配謂詞,定義了搜索的邏輯。上面的例子中,我們搜索了所有JavaScirpt文件(以.js結(jié)尾的文件名)。

我們可以使用Files.walk方法來(lái)完成相同的行為。這個(gè)方法會(huì)遍歷每個(gè)文件,而不需要傳遞搜索謂詞。

Path start = Paths.get("");
int maxDepth = 5;
try (Stream stream = Files.walk(start, maxDepth)) {
    String joined = stream
        .map(String::valueOf)
        .filter(path -> path.endsWith(".js"))
        .sorted()
        .collect(Collectors.joining("; "));
    System.out.println("walk(): " + joined);
}

這個(gè)例子中,我們使用了流式操作filter來(lái)完成和上個(gè)例子相同的行為。

讀寫文件

將文本文件讀到內(nèi)存,以及向文本文件寫入字符串在Java 8 中是簡(jiǎn)單的任務(wù)。不需要再去擺弄讀寫器了。Files.readAllLines從指定的文件把所有行讀進(jìn)字符串列表中。你可以簡(jiǎn)單地修改這個(gè)列表,并且將它通過(guò)Files.write寫到另一個(gè)文件中:

List lines = Files.readAllLines(Paths.get("res/nashorn1.js"));
lines.add("print("foobar");");
Files.write(Paths.get("res/nashorn1-modified.js"), lines);

要注意這些方法對(duì)內(nèi)存并不十分高效,因?yàn)檎麄€(gè)文件都會(huì)讀進(jìn)內(nèi)存。文件越大,所用的堆區(qū)也就越大。

你可以使用Files.lines方法來(lái)作為內(nèi)存高效的替代。這個(gè)方法讀取每一行,并使用函數(shù)式數(shù)據(jù)流來(lái)對(duì)其流式處理,而不是一次性把所有行都讀進(jìn)內(nèi)存。

try (Stream stream = Files.lines(Paths.get("res/nashorn1.js"))) {
    stream
        .filter(line -> line.contains("print"))
        .map(String::trim)
        .forEach(System.out::println);
}

如果你需要更多的精細(xì)控制,你需要構(gòu)造一個(gè)新的BufferedReader來(lái)代替:

Path path = Paths.get("res/nashorn1.js");
try (BufferedReader reader = Files.newBufferedReader(path)) {
    System.out.println(reader.readLine());
}

或者,你需要寫入文件時(shí),簡(jiǎn)單地構(gòu)造一個(gè)BufferedWriter來(lái)代替:

Path path = Paths.get("res/output.js");
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
    writer.write("print("Hello World");");
}

BufferedReader也可以訪問(wèn)函數(shù)式數(shù)據(jù)流。lines方法在它所有行上面構(gòu)建數(shù)據(jù)流:

Path path = Paths.get("res/nashorn1.js");
try (BufferedReader reader = Files.newBufferedReader(path)) {
    long countPrints = reader
        .lines()
        .filter(line -> line.contains("print"))
        .count();
    System.out.println(countPrints);
}

目前為止你可以看到Java8提供了三個(gè)簡(jiǎn)單的方法來(lái)讀取文本文件的每一行,使文件處理更加便捷。

不幸的是你需要顯式使用try-with語(yǔ)句來(lái)關(guān)閉文件流,這會(huì)使示例代碼有些凌亂。我期待函數(shù)式數(shù)據(jù)流可以在調(diào)用類似countcollect時(shí)可以自動(dòng)關(guān)閉,因?yàn)槟悴荒茉谙嗤瑪?shù)據(jù)流上調(diào)用終止操作兩次。

我希望你能喜歡這篇文章。所有示例代碼都托管在Github上,還有來(lái)源于我博客其它Java8文章的大量的代碼片段。如果這篇文章對(duì)你有所幫助,請(qǐng)收藏我的倉(cāng)庫(kù),并且在Twitter上關(guān)注我。

請(qǐng)堅(jiān)持編程!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64960.html

相關(guān)文章

  • Java 數(shù)據(jù)類型運(yùn)算符

    摘要:基本數(shù)據(jù)類型布爾類型或,占用位。強(qiáng)制類型轉(zhuǎn)換強(qiáng)制類型轉(zhuǎn)換的語(yǔ)法格式是,強(qiáng)制類型轉(zhuǎn)換的運(yùn)算符是圓括號(hào)。無(wú)符號(hào)右移運(yùn)算符。對(duì)于低于類型如和的操作數(shù)總是先自動(dòng)類型轉(zhuǎn)換為類型后再移位。 注釋 單行注釋//......多行注釋/ .../文檔注釋/*.../ 文檔注釋位于注釋內(nèi)容上一行 標(biāo)識(shí)符和關(guān)鍵字 分隔符 分號(hào):作為語(yǔ)句的分隔,每個(gè)Java語(yǔ)句必須使用分號(hào)作為結(jié)尾?;ɡㄌ?hào):定義一個(gè)代碼...

    archieyang 評(píng)論0 收藏0
  • JavaScript-算數(shù)運(yùn)算符

    摘要:浮點(diǎn)數(shù)運(yùn)算余數(shù)運(yùn)算符還可以用于浮點(diǎn)數(shù)的運(yùn)算。這些語(yǔ)言中的冪運(yùn)算符有著比其他的單目運(yùn)算符如一元或一元更高的優(yōu)先級(jí)。但是作為例外,在中,運(yùn)算符被設(shè)計(jì)為比單目運(yùn)算符優(yōu)先級(jí)更低。 一、算術(shù)運(yùn)算符 運(yùn)算符 描述 例子 x 運(yùn)算結(jié)果 y 運(yùn)算結(jié)果 + 加法 x=y+2 7 5 - 減法 x=y-2 3 5 * 乘法 x=y*2 10 5 / 除法 x=y/2 2.5 5 ...

    lindroid 評(píng)論0 收藏0
  • JavaScript權(quán)威指南》隨筆(一)

    摘要:每個(gè)構(gòu)造函數(shù)定義了一類對(duì)象,表示由構(gòu)造函數(shù)初始化對(duì)象的集合。嚴(yán)格模式下,明確禁止八進(jìn)制數(shù)。日期和時(shí)間構(gòu)造函數(shù)用來(lái)創(chuàng)建表示日期和時(shí)間的對(duì)象,包含方法。模式匹配函數(shù)是一個(gè)構(gòu)造函數(shù),創(chuàng)建正則表達(dá)式。布爾值表示兩種狀態(tài),使用保留字和。 《Javascript權(quán)威指南》就是前端工程師口中常說(shuō)的犀牛書,得名是因?yàn)橹形姆g出版的書籍封面是一只犀牛,是學(xué)習(xí)JavaScript的必讀書籍。 JavaSc...

    SwordFly 評(píng)論0 收藏0
  • 工具集核心教程 | 第六篇: Freemarker模板引擎入門到進(jìn)階

    摘要:到目前為止,使用越來(lái)越廣泛,不光光只是它強(qiáng)大的生成技術(shù),而且它能夠與進(jìn)行很好的集成。注意使用數(shù)字范圍來(lái)定義集合時(shí)無(wú)需使用方括號(hào)數(shù)字范圍也支持反遞增的數(shù)字范圍如對(duì)象對(duì)象使用花括號(hào)包括中的對(duì)之間以英文冒號(hào)分隔,多組對(duì)之間以英文逗號(hào)分隔。 Freemarker的介紹 ??Freemarker 是一款模板引擎,是一種基于模版生成靜態(tài)文件的通用 工具,它是為程序員提供的一個(gè)開發(fā)包,或者說(shuō)是一個(gè)類...

    趙連江 評(píng)論0 收藏0
  • Java零基礎(chǔ)入門筆記|原來(lái)學(xué)Java可以這么簡(jiǎn)單

    摘要:剛開始學(xué)習(xí)的時(shí)候,可能是一頭霧水,不知道從何學(xué)起。這個(gè)教程總體來(lái)說(shuō)就像列文虎克教學(xué),細(xì)到極致,妙到毫巔。適合絕對(duì)零基礎(chǔ)的,每個(gè)知識(shí)點(diǎn)掰開了揉碎了講解。 剛開始學(xué)習(xí)java的時(shí)候,可能是一頭霧水,不知道從何學(xué)起。還有很多Java小白,在剛自學(xué)Java的時(shí)候玩命的學(xué)習(xí),玩命的記住Java原理,天天早上五點(diǎn)起床背Java的一些英...

    2bdenny 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<