在Java中使用流拆分单词列表
我有一个方法,它需要许多列表,其中包含一行的书籍。我将它们合并到一个流中,然后对它们进行迭代,以拆分所有非字母的在Java中使用流拆分单词列表,java,regex,string,java-8,java-stream,Java,Regex,String,Java 8,Java Stream,我有一个方法,它需要许多列表,其中包含一行的书籍。我将它们合并到一个流中,然后对它们进行迭代,以拆分所有非字母的\\P{L} 有没有一种方法可以避免for-each循环并在流中处理它 private List<String> getWordList(List<String>... lists) { List<String> wordList = new ArrayList<>(); Stream<String
\\P{L}
有没有一种方法可以避免for-each循环并在流中处理它
private List<String> getWordList(List<String>... lists) {
List<String> wordList = new ArrayList<>();
Stream<String> combinedStream = Stream.of(lists)
.flatMap(Collection::stream);
List<String> combinedLists = combinedStream.collect(Collectors.toList());
for (String line: combinedLists) {
wordList.addAll(Arrays.asList(line.split("\\P{L}")));
}
return wordList;
}
私有列表getWordList(列表…列表){
List wordList=new ArrayList();
Stream combinedStream=Stream.of(列表)
.flatMap(集合::流);
List combinedLists=combinedStream.collect(Collectors.toList());
for(字符串行:组合列表){
addAll(Arrays.asList(line.split(\\P{L}));
}
返回词表;
}
拥有流,您只需进一步“flatMap
”并返回结果:
return combinedStream
.flatMap(str -> Arrays.stream(str.split("\\P{L}")))
.collect(Collectors.toList());
总而言之:
private List<String> getWordList(List<String>... lists) {
return Stream.of(lists)
.flatMap(Collection::stream)
.flatMap(str -> Arrays.stream(str.split("\\P{L}")))
.collect(Collectors.toList());
}
私有列表getWordList(列表…列表){
返回流.of(列表)
.flatMap(集合::流)
.flatMap(str->Arrays.stream(str.split(\\P{L})))
.collect(Collectors.toList());
}
您可以将所有列表和flatMap
合并以获得结果
private List<String> getWordList(List<String>... lists) {
return Stream.of(lists)
.flatMap(Collection::stream)
.flatMap(str -> Arrays.stream(str.split("\\P{L}")))
.collect(Collectors.toList());
}
私有列表getWordList(列表…列表){
返回流.of(列表)
.flatMap(集合::流)
.flatMap(str->Arrays.stream(str.split(\\P{L})))
.collect(Collectors.toList());
}
您不需要引入这么多变量:
private List<String> getWordList(List<String>... lists) {
return Stream.of(lists) // Stream<Stream<String>>
.flatMap(Collection::stream) // Stream<String>
.flatMap(Pattern.compile("\\P{L}")::splitAsStream) //Stream<String>
.collect(toList()); // List<String>
}
私有列表getWordList(列表…列表){
返回Stream.of(列表)//Stream
.flatMap(集合::流)//流
.flatMap(Pattern.compile(\\P{L}”)::splitAsStream)//流
.collect(toList());//列表
}
正如霍尔格所强调的,.flatMap(Pattern.compile(\\p{L}”)::splitAsStream)
应该优先于
.flatMap(s->Arrays.stream(s.split(\\P{L}”)
,以避免为流的每个元素执行数组分配和模式编译。str
在这里不是字符串,而是列表。因此,List.split()
无法编译。您错过了一个中间操作:如前所述,建议使用.flatMap(Pattern.compile(\\P{L}”)::splitAsStream)
,这样可以避免为每个流元素重新编译模式,并且不会填充可能较大的中间数组。@Holger非常感谢您的参考。我还没有在Java8中看到这个。但我不太喜欢这种情况下的方法引用(Pattern.splitAsStream(String)
至少对我来说并不常见),但根据你在另一篇文章中的评论,它是必需的,我明白了。我们也可以在流之外编译模式,但也不可怕。您还可以将模式移动到常量,如static final pattern NON_LETTER_CHARS=pattern.compile(\\P{L}”)
然后使用.flatMap(非字母字符::splitAsStream)
或.flatMap(s->NON字母字符.splitAsStream))
。最后,在使用s.split(\\P{L}”)
时,您还必须了解regex引擎。事实上,这就是我在注释编辑中引用的,对不起。这是一种方式,但也不可怕。