Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
apachecn-java-zh
提交
74ca454d
A
apachecn-java-zh
项目概览
OpenDocCN
/
apachecn-java-zh
11 个月 前同步成功
通知
5
Star
53
Fork
13
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
apachecn-java-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
74ca454d
编写于
5月 24, 2021
作者:
W
wizardforcel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
2021-05-24 23:32:31
上级
fcef0089
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
21 addition
and
21 deletion
+21
-21
new/java-coding-prob/06.md
new/java-coding-prob/06.md
+13
-13
new/java-coding-prob/09.md
new/java-coding-prob/09.md
+2
-2
new/java-proj/8.md
new/java-proj/8.md
+4
-4
new/learn-java12-prog/05.md
new/learn-java12-prog/05.md
+1
-1
new/master-java11/10.md
new/master-java11/10.md
+1
-1
未找到文件。
new/java-coding-prob/06.md
浏览文件 @
74ca454d
...
...
@@ -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
<String>
`来获取。如果我们可以利用并行处理(基准测试显示出更好的性能),那么通过调用`
parallel()
`方法来并行化`
Stream
<String>
`就非常简单了:
我们也可以尝试通过`
Files.lines()
`利用流。这一次,我们将文件作为一个懒惰的`
Stream
<String>
`来获取。如果我们可以利用并行处理(基准测试显示出更好的性能),那么通过调用`
parallel()
`方法来并行化`
Stream
<String>
`就非常简单了:
```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
<Path>
`,这是一个对象,我们可以使用它来迭代目录中的条目:
...
...
@@ -3027,7 +3027,7 @@ JDK10 中引入了支持字符集的`Scanner`构造器。
我们来看看
`Scanner`
和
`BufferedReader`
的区别。
# 扫描器与
缓冲阅读器
# 扫描器与
`BufferedReader`
那么,我们应该使用
`Scanner`
还是
`BufferedReader`
?好吧,如果我们需要解析这个文件,那么
`Scanner`
就是最好的方法,否则
`BufferedReader`
更合适,对它们进行一个正面比较,会发现:
...
...
new/java-coding-prob/09.md
浏览文件 @
74ca454d
...
...
@@ -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
()
...
...
new/java-proj/8.md
浏览文件 @
74ca454d
...
...
@@ -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`
:
...
...
new/learn-java12-prog/05.md
浏览文件 @
74ca454d
...
...
@@ -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`
类读写数据
...
...
new/master-java11/10.md
浏览文件 @
74ca454d
...
...
@@ -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
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录