使用Java中的流拆分单词列表

时间:2019-03-03 12:53:58

标签: java java-8 java-stream

我正在使用这种方法,该方法采用许多列表,其中包含几行书。我将它们组合到一个流中,然后遍历它们以拆分所有非字母的\\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;
}

3 个答案:

答案 0 :(得分:8)

有了视频流,您可以进一步简单地“ 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());
}

答案 1 :(得分:4)

您不需要引入太多变量:

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>
}

由Holger强调,.flatMap(Pattern.compile("\\P{L}")::splitAsStream)
应该优先于.flatMap(s -> Arrays.stream(s.split("\\P{L}"))),以节省对流的每个元素执行的数组分配和模式编译。

答案 2 :(得分:1)

您可以将所有列表和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());
}