当它说接口的方法 returns 时,API 是什么意思?
What it mean by the API when it says the interface's method returns something?
我知道我们不能实例化一个接口,但是在学习一本关于 Streams
的教程时,我感到很困惑。
我只会用代码部分来突出我不明白的部分。
// count occurences of each word in a Stream<String> sorted by word
Map<String, Long> wordCounts =
Files.lines(Paths.get("Chapter2Paragraph.txt"))
.map(line -> line.replaceAll("(?!')\p{P}", ""))
.flatMap(line -> pattern.splitAsStream(line))
.collect(Collectors.groupingBy(String::toLowerCase,
TreeMap::new, Collectors.counting()));
对于方法 flatMap
,当在 API 中点击时,它说:
Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)
那么这是什么意思呢?我有点了解它的作用,但我根本不了解它在幕后是如何工作的。在这种情况下,当 API 提到 return 时,它 return 是一个对象还是意味着它会替换当前流?此外,当使用 Streams
时,编译器是否真的创建了这些元素的对象,然后在完成后终止?
此外,从上面的代码来看,我只是想确保我是正确的。
当你有一个 Map<String, Long> wordCounts
变量时,是否意味着在流终止结束时,最终结果必须完全遵循类型推断?
flapMap()
将每个元素变成一个流(任何类型)。这些流连接在一起形成一个大流。
在您的示例中,在按照模式(未在问题中指定)分割每一行之后,整个文件被流式传输(作为一个流)。
您似乎已经基本正确地分析了情况,但您可能对某些中间步骤感到模糊。
您有一个方法链,调用链中前一个方法的 return 值。最终方法 (collect
) 的 return 值存储在名为 wordCounts
的 Map
中。忽略这些方法的确切作用和它们的作用 return(暂时),当您调用这样的方法链时,这是标准行为。
地图的通用类型由最终方法调用中的String::toLowerCase
和Collectors.counting()
决定。前者指定键类型为String
,后者指定值为Long
。例如,如果您使用 String::length
作为键,您将得到一个 Map<Integer, Long>
类型的映射,它会计算给定长度的单词出现的次数。
回到函数调用的顺序,可以细分如下:
文件中的 Files.lines(Path)
creates a Stream<String>
行。由于结果是一个流,您现在可以调用...
Stream.map(Function<String, String>)
使用对 line.replaceAll(...)
. 的调用将输入的字符串流转换为另一个字符串流
编辑行流现在得到 Stream.flatMap(Function<String, Stream<String>>)
以将行拆分为单词和 return 单个连续流。请记住,pattern.splitAsStream
将按顺序应用于每一行,因此 return 有多少行就有多少流。 Stream.flatMap
获取所有这些流并将它们串成一个连续的流。
请注意,封装的全部目的是您不必确切知道该过程在幕后是如何工作的。您只需要知道最终结果是什么(在本例中为 Stream<String>
)。您应该能够交换一个实现,该实现将所有流预先读取到底层集合中,并且 returns 一个流与一个在处理元素时懒惰地打开每个流的流,而不必担心真正发生的事情.
- 现在文件中有
Stream<String>
个单词,您可以应用所谓的终端操作:Stream.collect(Collector<String, String, Map<String, Long>>)
。收集器由 Collectors.groupingBy(Function<String, String>, Supplier<Map<String, String>>, Collector<String, String, Long>)
. This creates a collector that groups the input stream into sub-streams according to the key returned by the classifier Function
(String.toLowerCase()
) and passes it into a "downstream" collector to do the actual accumulation on each sub-stream. The resulting accumulation is stored into the map returned by the Supplier
(TreeMap::new
). The downstream Collector
is created by Collectors.counting()
创建,它只计算每个流中的元素数。
我已经扩展了此描述中的所有泛型类型,以便更容易理解并查看每个步骤产生的对象种类。
更笼统地说,Java 中的流有两种类型的操作:中间操作和终端操作。流来自一个源(在本例中是您的文件)。所有中间操作 (1-3) 将一个流变成另一个流。输入和输出类型始终明确定义,正如我在上面所示,就像任何其他操作一样。终端操作是 return 基于流的某种单一值。在你的例子中,你计算单词频率并将它们存储到 Map
中。这在 java.util.stream
package summary.
中有很好的记录
我知道我们不能实例化一个接口,但是在学习一本关于 Streams
的教程时,我感到很困惑。
我只会用代码部分来突出我不明白的部分。
// count occurences of each word in a Stream<String> sorted by word
Map<String, Long> wordCounts =
Files.lines(Paths.get("Chapter2Paragraph.txt"))
.map(line -> line.replaceAll("(?!')\p{P}", ""))
.flatMap(line -> pattern.splitAsStream(line))
.collect(Collectors.groupingBy(String::toLowerCase,
TreeMap::new, Collectors.counting()));
对于方法 flatMap
,当在 API 中点击时,它说:
Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)
那么这是什么意思呢?我有点了解它的作用,但我根本不了解它在幕后是如何工作的。在这种情况下,当 API 提到 return 时,它 return 是一个对象还是意味着它会替换当前流?此外,当使用 Streams
时,编译器是否真的创建了这些元素的对象,然后在完成后终止?
此外,从上面的代码来看,我只是想确保我是正确的。
当你有一个 Map<String, Long> wordCounts
变量时,是否意味着在流终止结束时,最终结果必须完全遵循类型推断?
flapMap()
将每个元素变成一个流(任何类型)。这些流连接在一起形成一个大流。
在您的示例中,在按照模式(未在问题中指定)分割每一行之后,整个文件被流式传输(作为一个流)。
您似乎已经基本正确地分析了情况,但您可能对某些中间步骤感到模糊。
您有一个方法链,调用链中前一个方法的 return 值。最终方法 (collect
) 的 return 值存储在名为 wordCounts
的 Map
中。忽略这些方法的确切作用和它们的作用 return(暂时),当您调用这样的方法链时,这是标准行为。
地图的通用类型由最终方法调用中的String::toLowerCase
和Collectors.counting()
决定。前者指定键类型为String
,后者指定值为Long
。例如,如果您使用 String::length
作为键,您将得到一个 Map<Integer, Long>
类型的映射,它会计算给定长度的单词出现的次数。
回到函数调用的顺序,可以细分如下:
-
文件中的
Files.lines(Path)
creates aStream<String>
行。由于结果是一个流,您现在可以调用...Stream.map(Function<String, String>)
使用对line.replaceAll(...)
. 的调用将输入的字符串流转换为另一个字符串流
编辑行流现在得到
Stream.flatMap(Function<String, Stream<String>>)
以将行拆分为单词和 return 单个连续流。请记住,pattern.splitAsStream
将按顺序应用于每一行,因此 return 有多少行就有多少流。Stream.flatMap
获取所有这些流并将它们串成一个连续的流。请注意,封装的全部目的是您不必确切知道该过程在幕后是如何工作的。您只需要知道最终结果是什么(在本例中为
Stream<String>
)。您应该能够交换一个实现,该实现将所有流预先读取到底层集合中,并且 returns 一个流与一个在处理元素时懒惰地打开每个流的流,而不必担心真正发生的事情.- 现在文件中有
Stream<String>
个单词,您可以应用所谓的终端操作:Stream.collect(Collector<String, String, Map<String, Long>>)
。收集器由Collectors.groupingBy(Function<String, String>, Supplier<Map<String, String>>, Collector<String, String, Long>)
. This creates a collector that groups the input stream into sub-streams according to the key returned by the classifierFunction
(String.toLowerCase()
) and passes it into a "downstream" collector to do the actual accumulation on each sub-stream. The resulting accumulation is stored into the map returned by theSupplier
(TreeMap::new
). The downstreamCollector
is created byCollectors.counting()
创建,它只计算每个流中的元素数。
我已经扩展了此描述中的所有泛型类型,以便更容易理解并查看每个步骤产生的对象种类。
更笼统地说,Java 中的流有两种类型的操作:中间操作和终端操作。流来自一个源(在本例中是您的文件)。所有中间操作 (1-3) 将一个流变成另一个流。输入和输出类型始终明确定义,正如我在上面所示,就像任何其他操作一样。终端操作是 return 基于流的某种单一值。在你的例子中,你计算单词频率并将它们存储到 Map
中。这在 java.util.stream
package summary.