diff --git a/new/java-coding-prob/06.md b/new/java-coding-prob/06.md index f6eee639f9aff9d123b69c84cde244d01885deb2..1ab81bcee380649f4d70ef0239f9e53f6f4084b3 100644 --- a/new/java-coding-prob/06.md +++ b/new/java-coding-prob/06.md @@ -372,7 +372,7 @@ Path path3 = Paths.get("D:/learning/packt/JavaModernChallenge.pdf"); 在下面的部分中,我们将研究用于比较文件路径的不同方法。 -# 路径.equals() +# `Path.equals()` `path1`等于`path2`吗?或者,`path2`等于`path3`吗?好吧,如果我们通过`Path.equals()`进行这些测试,那么可能的结果将显示`path1`等于`path2`,但`path2`不等于`path3`: @@ -400,7 +400,7 @@ boolean path1IsSameFilePath3 = Files.isSameFile(path1, path3); boolean path2IsSameFilePath3 = Files.isSameFile(path2, path3); ``` -# 辞书比较 +# 词典比较 如果我们只需要对路径进行词典比较,那么我们可以依赖于`Path.compareTo()`方法(这对于排序很有用)。 @@ -427,9 +427,9 @@ boolean sw = path1.startsWith("/learning/packt"); // true boolean ew = path1.endsWith("JavaModernChallenge.pdf"); // true ``` -# 134 步行道 +# 134 遍历 -对于行走(或访问)路径有不同的解决方案,其中一种由 NIO.2API 通过`FileVisitor`接口提供。 +对于遍历(或访问)路径有不同的解决方案,其中一种由 NIO.2API 通过`FileVisitor`接口提供。 此接口公开了一组方法,这些方法表示访问给定路径的递归过程中的检查点。通过覆盖这些检查点,我们可以干预这个过程。我们可以处理当前访问的文件/文件夹,并通过`FileVisitResult`枚举决定应该进一步执行的操作,该枚举包含以下常量: @@ -1247,7 +1247,7 @@ try (FileChannel fileChannel = (FileChannel.open(chineseFile, JDK13 准备发布非易失性`MappedByteBuffer`。敬请期待! -# 编写文本文件 +# 写入文本文件 对于每个专用于读取文本文件的类/方法(例如,`BufferedReader`和`readString()`),Java 提供其对应的用于写入文本文件的类/方法(例如,`BufferedWriter`和`writeString()`)。下面是通过`BufferedWriter`写入文本文件的示例: @@ -1545,7 +1545,7 @@ public static int countOccurrences(Path path, String text, Charset ch) } ``` -# 解决方案基于文件.readAllLines() +# 基于`Files.readAllLines()`的解决方案 如果内存(RAM)对我们来说不是问题,那么我们可以尝试将整个文件读入内存(通过`Files.readAllLines()`并从那里处理它。将整个文件放在内存中支持并行处理。因此,如果我们的硬件可以通过并行处理突出显示,那么我们可以尝试依赖`parallelStream()`,如下所示: @@ -1561,9 +1561,9 @@ public static int countOccurrences(Path path, String text, Charset ch) 如果`parallelStream()`没有任何好处,那么我们可以简单地切换到`stream()`。这只是一个基准问题。 -# 解决方案基于文件.lines() +# 基于`Files.lines()`的解决方案 -我们也可以尝试通过`Files.lines()`利用溪流。这一次,我们将文件作为一个懒惰的`Stream`来获取。如果我们可以利用并行处理(基准测试显示出更好的性能),那么通过调用`parallel()`方法来并行化`Stream`就非常简单了: +我们也可以尝试通过`Files.lines()`利用流。这一次,我们将文件作为一个懒惰的`Stream`来获取。如果我们可以利用并行处理(基准测试显示出更好的性能),那么通过调用`parallel()`方法来并行化`Stream`就非常简单了: ```java public static int countOccurrences(Path path, String text, Charset ch) @@ -1643,11 +1643,11 @@ public static int countOccurrences(Path path, String text) 这个解决方案非常快,因为文件直接从操作系统的内存中读取,而不必加载到 JVM 中。这些操作在本机级别进行,称为操作系统级别。请注意,此实现仅适用于 UTF-8 字符集,但也可以适用于其他字符集。 -# 141 将 JSON/CSV 文件作为对象读取 +# 141 将 JSON/CSV 文件读取为对象 如今,JSON 和 CSV 文件无处不在。读取(反序列化)JSON/CSV 文件可能是一项日常任务,通常位于业务逻辑之前。编写(序列化)JSON/CSV 文件也是一项常见的任务,通常发生在业务逻辑的末尾。在读写这些文件之间,应用将数据用作对象。 -# 将 JSON 文件作为对象读/写 +# 将 JSON 文件读/写为对象 让我们从三个文本文件开始,它们代表典型的类似 JSON 的映射: @@ -2070,11 +2070,11 @@ try (BufferedWriter bw = Files.newBufferedWriter(tmpFile, 此解决方案可用于任何文件。它不是针对临时资源的。 -# 143 筛选文件 +# 143 过滤文件 从`Path`中过滤文件是一项非常常见的任务。例如,我们可能只需要特定类型的文件、具有特定名称模式的文件、今天修改的文件等等。 -# 过滤通过文件.newDirectoryStream() +# 通过`Files.newDirectoryStream()`过滤 不需要任何类型的过滤器,我们可以通过`Files.newDirectoryStream(Path dir)`方法轻松地循环文件夹的内容(一层深)。此方法返回一个`DirectoryStream`,这是一个对象,我们可以使用它来迭代目录中的条目: @@ -3027,7 +3027,7 @@ JDK10 中引入了支持字符集的`Scanner`构造器。 我们来看看`Scanner`和`BufferedReader`的区别。 -# 扫描器与缓冲阅读器 +# 扫描器与`BufferedReader` 那么,我们应该使用`Scanner`还是`BufferedReader`?好吧,如果我们需要解析这个文件,那么`Scanner`就是最好的方法,否则`BufferedReader`更合适,对它们进行一个正面比较,会发现: diff --git a/new/java-coding-prob/09.md b/new/java-coding-prob/09.md index ecac050f3a2037e3d7810d315f81376c68a0e10c..3db0fb49f3d92e07164f1b3a0f3dcb0b27644d69 100644 --- a/new/java-coding-prob/09.md +++ b/new/java-coding-prob/09.md @@ -395,7 +395,7 @@ private static boolean evenBetween0And10(int value) { 在这个问题的第一部分,我们将讨论无限流。在第二部分中,我们将讨论`takeWhile()`和`dropWhile()`api。 -无限流是无限期地创建数据的流。因为溪流是懒惰的,它们可以是无限的。更准确地说,创建无限流是作为中间操作完成的,因此在执行管道的终端操作之前,不会创建任何数据。 +无限流是无限期地创建数据的流。因为流是懒惰的,它们可以是无限的。更准确地说,创建无限流是作为中间操作完成的,因此在执行管道的终端操作之前,不会创建任何数据。 例如,下面的代码理论上将永远运行。此行为由`forEach()`终端操作触发,并由缺少约束或限制引起: @@ -1600,7 +1600,7 @@ long numberOfWords = Stream.of(str) .count(); ``` -但是让我们看看我们的溪流里有多少重 3000 磅的`Melon`: +但是让我们看看我们的流里有多少重 3000 磅的`Melon`: ```java long nrOfMelon = melons.stream() diff --git a/new/java-proj/8.md b/new/java-proj/8.md index 6800bcc21adaa9d2109fa734d0c4edca8a995d22..61085a0151e2181f7c19868e1b8125aaa26efc16 100644 --- a/new/java-proj/8.md +++ b/new/java-proj/8.md @@ -10,7 +10,7 @@ * 使用反射 * Java 函数式编程使用: * Lambda 表达式 -* 溪流 +* 流 * 从 Java 调用脚本 # 我的业务订单 @@ -747,7 +747,7 @@ sort.setComparator((var a, var b) -> { 当我们想将函数作为参数传递时,Lambda 表达式非常方便。方法声明处参数类型的声明应为函数式接口类型。这些接口可以选择使用`@FunctionalInterface`进行注释。Java 运行时在`java.util.function`包中定义了许多这样的接口。我们将在下一节讨论其中的一些,以及它们在流中的使用。对于其余部分,标准 Java 文档可从 Oracle 获得。 -# 溪流 +# 流 流在 Java8 中也是新的,就像 Lambda 表达式一样。他们一起工作非常强烈,所以他们的出现在同一时间并不令人惊讶。Lambda 表达式以及流都支持函数式编程风格。 @@ -755,7 +755,7 @@ sort.setComparator((var a, var b) -> { 流支持对多个数据执行相同的计算。该结构称为**单指令多数据**(**SIMD**)。别害怕这个表情。这是一件非常简单的事情。这本书我们已经做了很多次了。循环也是一种 SIMD 结构。当我们循环检查类以查看其中是否有一个反对该顺序时,我们对每个和每个检查程序执行相同的指令。多个检查器意味着多个数据。 -循环的一个问题是,我们定义了不需要的执行顺序。在跳棋的情况下,我们并不关心跳棋的执行顺序。我们关心的是,所有人都同意这个命令。在编程循环时,我们仍然指定一些顺序。这来自循环的本质,我们无法改变这一点。他们就是这样工作的。然而,如果我们能,不知何故,说“对每个检查者做这个和那个”,那就太好了。这就是溪流发挥作用的地方。 +循环的一个问题是,我们定义了不需要的执行顺序。在跳棋的情况下,我们并不关心跳棋的执行顺序。我们关心的是,所有人都同意这个命令。在编程循环时,我们仍然指定一些顺序。这来自循环的本质,我们无法改变这一点。他们就是这样工作的。然而,如果我们能,不知何故,说“对每个检查者做这个和那个”,那就太好了。这就是流发挥作用的地方。 另一点是,使用循环的代码更重要,而不是描述性的。当我们阅读循环构造的程序时,我们将重点放在各个步骤上。我们首先看到循环中的命令是做什么的。这些命令作用于数据的单个元素,而不是整个集合或数组。 @@ -1056,7 +1056,7 @@ public boolean isConsistent(Order order) { } ``` -因为您已经学习了大多数重要的流方法,所以这里几乎没有什么新问题。我们可以提到`anyMatch()`方法,如果至少有一个元素,则返回`true`,这样传递给`anyMatch()`的`Predicate`参数就是`true`。它可能还需要一些住宿,这样我们就可以使用另一条溪流中的一条溪流。这很可能是一个例子,当一个流表达式过于复杂,需要使用局部变量分解成更小的片段。 +因为您已经学习了大多数重要的流方法,所以这里几乎没有什么新问题。我们可以提到`anyMatch()`方法,如果至少有一个元素,则返回`true`,这样传递给`anyMatch()`的`Predicate`参数就是`true`。它可能还需要一些住宿,这样我们就可以使用另一条流中的一条流。这很可能是一个例子,当一个流表达式过于复杂,需要使用局部变量分解成更小的片段。 最后,在离开函数样式之前,我们重写了`CheckHelper`类中的`containsOneOf()`方法。这不包含新元素,将帮助您检查您对`map()`、`filter()`、`flatMap()`和`Collector`的了解。请注意,如我们所讨论的,如果`order`至少包含一个以字符串形式给出的订单 ID,则此方法返回`true`: diff --git a/new/learn-java12-prog/05.md b/new/learn-java12-prog/05.md index 40debc55f054a5010419a55e9d5e7fd37d1ba15a..c3f83d54b90d85dd7315178b54dcda4576f722dd 100644 --- a/new/learn-java12-prog/05.md +++ b/new/learn-java12-prog/05.md @@ -353,7 +353,7 @@ System.out.println("'" + StringUtils.trimToEmpty(" ") + "'"); // '' # I/O 流 -任何软件系统都必须接收和生成某种数据,这些数据可以组织为一组独立的输入/输出或数据流。溪流可以是有限的,也可以是无穷无尽的。一个程序可以从一个流中读取(然后称为一个**输入流**),或者写入一个流(然后称为一个**输出流**)。java I/O 流要么基于字节,要么基于字符,这意味着它的数据要么被解释为原始字节,要么被解释为字符。 +任何软件系统都必须接收和生成某种数据,这些数据可以组织为一组独立的输入/输出或数据流。流可以是有限的,也可以是无穷无尽的。一个程序可以从一个流中读取(然后称为一个**输入流**),或者写入一个流(然后称为一个**输出流**)。java I/O 流要么基于字节,要么基于字符,这意味着它的数据要么被解释为原始字节,要么被解释为字符。 `java.io`包包含支持许多(但不是所有)可能数据源的类。它主要围绕文件、网络流和内部内存缓冲区的输入来构建。它不包含许多网络通信所必需的类。它们属于 Java 网络 API 的`java.net`、`javax.net`等包。只有在建立了网络源或目的地(例如网络套接字)之后,程序才能使用`java.io`包的`InputStream`和`OutputStream`类读写数据 diff --git a/new/master-java11/10.md b/new/master-java11/10.md index 5af63d5bd079e15e45995f97ee18e6c6a17ec560..7711b4a58071bf5cb15de67fba9d923fddd40399 100644 --- a/new/master-java11/10.md +++ b/new/master-java11/10.md @@ -121,7 +121,7 @@ public class CheckEligibility { 一开始,这个参数设置似乎很复杂,很难理解。更合乎逻辑的做法是返回提供`StackFrame`对象的`Stream`,而不是强制调用者定义一个将其作为参数的函数。 -示例代码使用 Lambda 表达式将函数定义为`walk()`方法的参数。Lambda 表达式的参数是流。因为这个流的第一个元素是实际的调用,所以我们放弃它。因为如果调用方不符合条件,也应该拒绝这些调用,即使对`hello()`方法的调用是通过库中已经存在的其他类和方法进行的,所以我们从框架中删除属于`CheckEligibility`类包中类的所有元素。这个包是`packt.java9.deep.stackwalker.myrestrictivelibrary`,在代码中,这个字符串存储在`packageName`字段中。结果流只包含来自库外部的`StackFrame`对象。我们把这些也扔下去,直到溪流耗尽,或者直到我们发现`StackFrame`又属于图书馆。如果所有的元素都消失了,我们就好了。在这种情况下,`count()`的结果为零。如果我们在`StackFrame`中找到一个属于库的类,这意味着外部代码是从库中调用的,在这种情况下,我们必须拒绝工作。在这种情况下,变量`eligible`将是`false`,我们抛出一个异常,如下面的屏幕截图所示: +示例代码使用 Lambda 表达式将函数定义为`walk()`方法的参数。Lambda 表达式的参数是流。因为这个流的第一个元素是实际的调用,所以我们放弃它。因为如果调用方不符合条件,也应该拒绝这些调用,即使对`hello()`方法的调用是通过库中已经存在的其他类和方法进行的,所以我们从框架中删除属于`CheckEligibility`类包中类的所有元素。这个包是`packt.java9.deep.stackwalker.myrestrictivelibrary`,在代码中,这个字符串存储在`packageName`字段中。结果流只包含来自库外部的`StackFrame`对象。我们把这些也扔下去,直到流耗尽,或者直到我们发现`StackFrame`又属于图书馆。如果所有的元素都消失了,我们就好了。在这种情况下,`count()`的结果为零。如果我们在`StackFrame`中找到一个属于库的类,这意味着外部代码是从库中调用的,在这种情况下,我们必须拒绝工作。在这种情况下,变量`eligible`将是`false`,我们抛出一个异常,如下面的屏幕截图所示: ![](img/8da943bd-0406-4257-8bcb-2707259cb2a4.png)