为什么 Java8 flatmap 返回一个 List of List?
Why is Java8 flatmap returning a List of List?
我正在尝试使用以下 java 8 代码将 'applying' List
个函数实现到 List
个 File
个对象。
List<Function<File, String>> mappingFunctions = Arrays.asList(
(file) -> file.getName(),
(file) -> file.getPath(),
(file) -> ((Long) file.length()).toString(),
(file) -> file.isDirectory() ? "Directory" : "File"
);
// collects all files in this and one level down directory
List<File> files =
Stream.of(new File(".").listFiles())
.flatMap(file -> file.listFiles() == null ? Stream.of(file) : Stream.of(file.listFiles()))
.collect(toList());
System.out.println("All the files gathered ...\n");
files.forEach(System.out::println);
System.out.println("\nApplying the list of functions to all the files gathered ...\n");
files.stream()
.flatMap(file -> Stream.of(mappingFunctions.stream()
.map((func) -> func.apply(file))
.collect(Collectors.toList())))
.forEach(System.out::println);
我得到的输出如下,
All the files gathered ...
.\.idea\compiler.xml
.\.idea\copyright
.\.idea\description.html
.\.idea\dictionaries
.\.idea\encodings.xml
.\.idea\misc.xml
.\.idea\modules.xml
.\.idea\project-template.xml
.\.idea\scopes
.\.idea\uiDesigner.xml
.\.idea\vcs.xml
.\.idea\workspace.xml
.\out\production
.\src\com
.\Test.iml
正在将函数列表应用于收集到的所有文件...
[compiler.xml, .\.idea\compiler.xml, 739, File]
[copyright, .\.idea\copyright, 0, Directory]
[description.html, .\.idea\description.html, 97, File]
[dictionaries, .\.idea\dictionaries, 0, Directory]
[encodings.xml, .\.idea\encodings.xml, 164, File]
[misc.xml, .\.idea\misc.xml, 525, File]
[modules.xml, .\.idea\modules.xml, 255, File]
[project-template.xml, .\.idea\project-template.xml, 91, File]
[scopes, .\.idea\scopes, 0, Directory]
[uiDesigner.xml, .\.idea\uiDesigner.xml, 8792, File]
[vcs.xml, .\.idea\vcs.xml, 164, File]
[workspace.xml, .\.idea\workspace.xml, 28470, File]
[production, .\out\production, 0, Directory]
[com, .\src\com, 0, Directory]
[Test.iml, .\Test.iml, 437, File]
问题 1:为什么我在第二个输出中得到一个列表列表,而在第一个输出中只有一个列表?他们都在集合流上使用平面图。
问题 2:在 Java 8 中是否有更好的方法来实现同样的目标?
在第二种情况下,flatMap
方法生成了一个 Stream<List<String>>
,其单个元素是 List<String>
。
在第一种情况下,flatMap
方法要么生成单个 File
的 Stream<File>
,要么生成 File
数组的 Stream<File>
。
注意有两种Stream.of
方法:
接受类型 T 的数组(或可变数量的 T 参数)并生成 T 的流:
of(T... values)
写的时候用到这个方法:
.flatMap(file -> Stream.of(file.listFiles()))
另一个接受单个 T 并生成具有单个元素 T 的 Stream:
of(T t)
写的时候用到这个方法:
.flatMap(file -> Stream.of(.. some expression that produces a List ..))
如果您希望最终流处理生成单个字符串流:
files.stream()
.flatMap(file -> mappingFunctions.stream()
.map((func) -> func.apply(file)))
.forEach(System.out::println);
这样,flatMap
中的 lambda 表达式将生成 Stream<String>
,而 flatMap
会将那些 Stream
扁平化为单个 Stream<String>
。
我正在尝试使用以下 java 8 代码将 'applying' List
个函数实现到 List
个 File
个对象。
List<Function<File, String>> mappingFunctions = Arrays.asList(
(file) -> file.getName(),
(file) -> file.getPath(),
(file) -> ((Long) file.length()).toString(),
(file) -> file.isDirectory() ? "Directory" : "File"
);
// collects all files in this and one level down directory
List<File> files =
Stream.of(new File(".").listFiles())
.flatMap(file -> file.listFiles() == null ? Stream.of(file) : Stream.of(file.listFiles()))
.collect(toList());
System.out.println("All the files gathered ...\n");
files.forEach(System.out::println);
System.out.println("\nApplying the list of functions to all the files gathered ...\n");
files.stream()
.flatMap(file -> Stream.of(mappingFunctions.stream()
.map((func) -> func.apply(file))
.collect(Collectors.toList())))
.forEach(System.out::println);
我得到的输出如下,
All the files gathered ...
.\.idea\compiler.xml
.\.idea\copyright
.\.idea\description.html
.\.idea\dictionaries
.\.idea\encodings.xml
.\.idea\misc.xml
.\.idea\modules.xml
.\.idea\project-template.xml
.\.idea\scopes
.\.idea\uiDesigner.xml
.\.idea\vcs.xml
.\.idea\workspace.xml
.\out\production
.\src\com
.\Test.iml
正在将函数列表应用于收集到的所有文件...
[compiler.xml, .\.idea\compiler.xml, 739, File]
[copyright, .\.idea\copyright, 0, Directory]
[description.html, .\.idea\description.html, 97, File]
[dictionaries, .\.idea\dictionaries, 0, Directory]
[encodings.xml, .\.idea\encodings.xml, 164, File]
[misc.xml, .\.idea\misc.xml, 525, File]
[modules.xml, .\.idea\modules.xml, 255, File]
[project-template.xml, .\.idea\project-template.xml, 91, File]
[scopes, .\.idea\scopes, 0, Directory]
[uiDesigner.xml, .\.idea\uiDesigner.xml, 8792, File]
[vcs.xml, .\.idea\vcs.xml, 164, File]
[workspace.xml, .\.idea\workspace.xml, 28470, File]
[production, .\out\production, 0, Directory]
[com, .\src\com, 0, Directory]
[Test.iml, .\Test.iml, 437, File]
问题 1:为什么我在第二个输出中得到一个列表列表,而在第一个输出中只有一个列表?他们都在集合流上使用平面图。
问题 2:在 Java 8 中是否有更好的方法来实现同样的目标?
在第二种情况下,flatMap
方法生成了一个 Stream<List<String>>
,其单个元素是 List<String>
。
在第一种情况下,flatMap
方法要么生成单个 File
的 Stream<File>
,要么生成 File
数组的 Stream<File>
。
注意有两种Stream.of
方法:
接受类型 T 的数组(或可变数量的 T 参数)并生成 T 的流:
of(T... values)
写的时候用到这个方法:
.flatMap(file -> Stream.of(file.listFiles()))
另一个接受单个 T 并生成具有单个元素 T 的 Stream:
of(T t)
写的时候用到这个方法:
.flatMap(file -> Stream.of(.. some expression that produces a List ..))
如果您希望最终流处理生成单个字符串流:
files.stream()
.flatMap(file -> mappingFunctions.stream()
.map((func) -> func.apply(file)))
.forEach(System.out::println);
这样,flatMap
中的 lambda 表达式将生成 Stream<String>
,而 flatMap
会将那些 Stream
扁平化为单个 Stream<String>
。