<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 處理字符串 兩個新的方法可在字符串類上使用:`join`和`chars`。第一個方法使用指定的分隔符,將任何數量的字符串連接為一個字符串。 ~~~java String.join(":", "foobar", "foo", "bar"); // => foobar:foo:bar ~~~ 第二個方法`chars`從字符串所有字符創建數據流,所以你可以在這些字符上使用流式操作。 ~~~java "foobar:foo:bar" .chars() .distinct() .mapToObj(c -> String.valueOf((char)c)) .sorted() .collect(Collectors.joining()); // => :abfor ~~~ 不僅僅是字符串,正則表達式模式串也能受益于數據流。我們可以分割任何模式串,并創建數據流來處理它們,而不是將字符串分割為單個字符的數據流,像下面這樣: ~~~java Pattern.compile(":") .splitAsStream("foobar:foo:bar") .filter(s -> s.contains("bar")) .sorted() .collect(Collectors.joining(":")); // => bar:foobar ~~~ 此外,正則模式串可以轉換為謂詞。這些謂詞可以像下面那樣用于過濾字符串流: ~~~java Pattern pattern = Pattern.compile(".*@gmail\\.com"); Stream.of("bob@gmail.com", "alice@hotmail.com") .filter(pattern.asPredicate()) .count(); // => 1 ~~~ 上面的模式串接受任何以`@gmail.com`結尾的字符串,并且之后用作Java8的`Predicate`來過濾電子郵件地址流。 ## [](https://github.com/wizardforcel/modern-java-zh/blob/master/ch7.md#處理數值)處理數值 Java8添加了對無符號數的額外支持。Java中的數值總是有符號的,例如,讓我們來觀察`Integer`: `int`可表示最多`2 ** 32`個數。Java中的數值默認為有符號的,所以最后一個二進制數字表示符號(0為正數,1為負數)。所以從十進制的0開始,最大的有符號正整數為`2 ** 31 - 1`。 你可以通過`Integer.MAX_VALUE`來訪問它: ~~~java System.out.println(Integer.MAX_VALUE); // 2147483647 System.out.println(Integer.MAX_VALUE + 1); // -2147483648 ~~~ Java8添加了解析無符號整數的支持,讓我們看看它如何工作: ~~~java long maxUnsignedInt = (1l << 32) - 1; String string = String.valueOf(maxUnsignedInt); int unsignedInt = Integer.parseUnsignedInt(string, 10); String string2 = Integer.toUnsignedString(unsignedInt, 10); ~~~ 就像你看到的那樣,現在可以將最大的無符號數`2 ** 32 - 1`解析為整數。而且你也可以將這個數值轉換回無符號數的字符串表示。 這在之前不可能使用`parseInt`完成,就像這個例子展示的那樣: ~~~java try { Integer.parseInt(string, 10); } catch (NumberFormatException e) { System.err.println("could not parse signed int of " + maxUnsignedInt); } ~~~ 這個數值不可解析為有符號整數,因為它超出了最大范圍`2 ** 31 - 1`。 ## [](https://github.com/wizardforcel/modern-java-zh/blob/master/ch7.md#算術運算)算術運算 `Math`工具類新增了一些方法來處理數值溢出。這是什么意思呢?我們已經看到了所有數值類型都有最大值。所以當算術運算的結果不能被它的大小裝下時,會發生什么呢? ~~~java System.out.println(Integer.MAX_VALUE); // 2147483647 System.out.println(Integer.MAX_VALUE + 1); // -2147483648 ~~~ 就像你看到的那樣,發生了整數溢出,這通常是我們不愿意看到的。 Java8添加了嚴格數學運算的支持來解決這個問題。`Math`擴展了一些方法,它們全部以`exact`結尾,例如`addExact`。當運算結果不能被數值類型裝下時,這些方法通過拋出`ArithmeticException`異常來合理地處理溢出。 ~~~java try { Math.addExact(Integer.MAX_VALUE, 1); } catch (ArithmeticException e) { System.err.println(e.getMessage()); // => integer overflow } ~~~ 當嘗試通過`toIntExact`將長整數轉換為整數時,可能會拋出同樣的異常: ~~~java try { Math.toIntExact(Long.MAX_VALUE); } catch (ArithmeticException e) { System.err.println(e.getMessage()); // => integer overflow } ~~~ ## [](https://github.com/wizardforcel/modern-java-zh/blob/master/ch7.md#處理文件)處理文件 `Files`工具類首次在Java7中引入,作為NIO的一部分。JDK8 API添加了一些額外的方法,它們可以將文件用于函數式數據流。讓我們深入探索一些代碼示例。 ### [](https://github.com/wizardforcel/modern-java-zh/blob/master/ch7.md#列出文件)列出文件 `Files.list`方法將指定目錄的所有路徑轉換為數據流,便于我們在文件系統的內容上使用類似`filter`和`sorted`的流操作。 ~~~java try (Stream<Path> stream = Files.list(Paths.get(""))) { String joined = stream .map(String::valueOf) .filter(path -> !path.startsWith(".")) .sorted() .collect(Collectors.joining("; ")); System.out.println("List: " + joined); } ~~~ 上面的例子列出了當前工作目錄的所有文件,之后將每個路徑都映射為它的字符串表示。之后結果被過濾、排序,最后連接為一個字符串。如果你還不熟悉函數式數據流,你應該閱讀我的[Java8數據流教程](https://github.com/wizardforcel/modern-java-zh/blob/master/ch2.md)。 你可能已經注意到,數據流的創建包裝在`try-with`語句中。數據流實現了`AutoCloseable`,并且這里我們需要顯式關閉數據流,因為它基于IO操作。 > 返回的數據流是`DirectoryStream`的封裝。如果需要及時處理文件資源,就應該使用`try-with`結構來確保在流式操作完成后,數據流的`close`方法被調用。 ### [](https://github.com/wizardforcel/modern-java-zh/blob/master/ch7.md#查找文件)查找文件 下面的例子演示了如何查找在目錄及其子目錄下的文件: ~~~java Path start = Paths.get(""); int maxDepth = 5; try (Stream<Path> 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`方法接受三個參數:目錄路徑`start`是起始點,`maxDepth`定義了最大搜索深度。第三個參數是一個匹配謂詞,定義了搜索的邏輯。上面的例子中,我們搜索了所有JavaScirpt文件(以`.js`結尾的文件名)。 我們可以使用`Files.walk`方法來完成相同的行為。這個方法會遍歷每個文件,而不需要傳遞搜索謂詞。 ~~~java Path start = Paths.get(""); int maxDepth = 5; try (Stream<Path> 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); } ~~~ 這個例子中,我們使用了流式操作`filter`來完成和上個例子相同的行為。 ### [](https://github.com/wizardforcel/modern-java-zh/blob/master/ch7.md#讀寫文件)讀寫文件 將文本文件讀到內存,以及向文本文件寫入字符串在Java 8 中是簡單的任務。不需要再去擺弄讀寫器了。`Files.readAllLines`從指定的文件把所有行讀進字符串列表中。你可以簡單地修改這個列表,并且將它通過`Files.write`寫到另一個文件中: ~~~java List<String> lines = Files.readAllLines(Paths.get("res/nashorn1.js")); lines.add("print('foobar');"); Files.write(Paths.get("res/nashorn1-modified.js"), lines); ~~~ 要注意這些方法對內存并不十分高效,因為整個文件都會讀進內存。文件越大,所用的堆區也就越大。 你可以使用`Files.lines`方法來作為內存高效的替代。這個方法讀取每一行,并使用函數式數據流來對其流式處理,而不是一次性把所有行都讀進內存。 ~~~java try (Stream<String> stream = Files.lines(Paths.get("res/nashorn1.js"))) { stream .filter(line -> line.contains("print")) .map(String::trim) .forEach(System.out::println); } ~~~ 如果你需要更多的精細控制,你需要構造一個新的`BufferedReader`來代替: ~~~java Path path = Paths.get("res/nashorn1.js"); try (BufferedReader reader = Files.newBufferedReader(path)) { System.out.println(reader.readLine()); } ~~~ 或者,你需要寫入文件時,簡單地構造一個`BufferedWriter`來代替: ~~~java Path path = Paths.get("res/output.js"); try (BufferedWriter writer = Files.newBufferedWriter(path)) { writer.write("print('Hello World');"); } ~~~ `BufferedReader`也可以訪問函數式數據流。`lines`方法在它所有行上面構建數據流: ~~~java 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提供了三個簡單的方法來讀取文本文件的每一行,使文件處理更加便捷。 不幸的是你需要顯式使用`try-with`語句來關閉文件流,這會使示例代碼有些凌亂。我期待函數式數據流可以在調用類似`count`和`collect`時可以自動關閉,因為你不能在相同數據流上調用終止操作兩次。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看