以下是使用Java 8流的代码:
Set<String> getFields( Path xml ) {
final Set<String> fields = new HashSet<>();
for( ... ) {
...
fields.add( ... );
...
}
return fields;
}
void scan() {
final SortedSet<Path> files = new TreeSet<>();
final Path root = new File( "....." ).toPath();
final BiPredicate<Path, BasicFileAttributes> pred =
(p,a) -> p.toString().toLowerCase().endsWith( ".xml" );
Files.find( root, 1, pred ).forEach( files::add );
final SortedSet<String> fields = new TreeSet<>();
files
.stream()
.parallel()
.map( this::getFields )
.forEach( s -> fields.addAll( s ));
// Do something with fields...
}
我想把map( this::getFields )
的结果合并,即将一个Stream<Set<Path>>
转换成Set<Path>
,但我不确定如何正确使用forEach
。
Jon Skeet回答后编辑内容,以总结评论并编译代码
Stream<String> getFields( Path xml ) {
final Set<String> fields = new HashSet<>();
for( ... ) {
...
fields.add( ... );
...
}
return fields.stream(); // returns a stream to ease integration
}
void scan() {
final Path root = new File( "....." ).toPath();
final BiPredicate<Path, BasicFileAttributes> pred =
(p,a) -> p.toString().toLowerCase().endsWith( ".xml" );
final SortedSet<Path> files =
Files
.find( root, 1, pred )
.collect( Collectors.toCollection( TreeSet::new ));
final SortedSet<String> fields =
files
.stream()
.parallel()
.flatMap( this::getFields )
.collect( Collectors.toCollection( TreeSet::new ));
// Do something with fields...
}
两个流可以合并成一个,但是后面会重复使用
files
。
flatMap
需要一个返回流的函数...所以也许可以使用flatMap(x -> getFields(x).stream())
?我也没有尝试过。 - ajb.map(this::getFields).flatMap(Set::stream).collect(...)
- assyliascollect(Collectors.toCollection(() -> new TreeSet<String>())
吗?需要两次提到集合好像有点奇怪... - Jon Skeetcollect(Collectors.toCollection(TreeSet::new))
。 - Stuart Marks