java 如何在java Stream中捕获拆分的字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29807947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:58:48  来源:igfitidea点击:

How to catch splitted string in java Stream

javajava-8

提问by Kaspar

So let's say that we have a string: "randomText1 randomText2" in an array, which is loaded into a Stream.

所以假设我们有一个字符串:“randomText1 randomText2”在一个数组中,它被加载到一个流中。

Now I go over all the lines in this stream, and I split every line at the space character.

现在我检查这个流中的所有行,并在空格字符处拆分每一行。

strings
                        .map(string -> string.split(" "))
                        .flatMap(Arrays::stream)
                        .collect(new MyClass(string1, string2));

How can I get the both sides of the string and do whatever I want with them from there on?

我怎样才能得到字符串的两边并从那里开始做我想做的任何事情?

From Oracle docs (Oracle doc link) I only managed to find some harder cases where one would be using a Map<>for instance. But I fail to fit their solutions to this more simpler problem of mine.

从 Oracle 文档(Oracle 文档链接)中,我只能找到一些更难的案例,Map<>例如,人们将使用 a 。但是我无法将他们的解决方案适合我这个更简单的问题。

回答by Holger

Using flatMapis not the right tool for the job. What you apparently want to do is

使用flatMap不是工作的正确工具。你显然想要做的是

strings.map(string -> string.split(" ", 2))
       .map(array  -> new MyClass(array[0], array[1]))

You may process the stream further by using .collect(Collectors.toList())to get a List<MyClass>or .findAny()to get a single MyClassinstance (if any).

您可以通过使用.collect(Collectors.toList())获取List<MyClass>.findAny()获取单个MyClass实例(如果有)来进一步处理流。

Generally, streaming an array is only useful if you want to treat all elements uniformly, i.e. notif their position has a special meaning which has to be preserved for subsequent operations.

通常,流式传输数组仅在您想统一处理所有元素时才有用,即如果它们的位置具有特殊含义,必须为后续操作保留该含义,则无效



And ifyou really want to create a flat stream of words or tokens, you shouldn't use the combination of String.splitand Arrays.streamas that will create and fill an unnecessary intermediate array. In this case use

而且,如果你真的想创造的词或令牌的扁平流,你不应该使用的组合String.split,并Arrays.stream为将创建并填写不必要的中间阵列。在这种情况下使用

strings.flatMap(Pattern.compile(" ")::splitAsStream)

see Pattern.splitAsStream

Pattern.splitAsStream

回答by lbalazscs

It was an interesting challenge even if streams should not be used for such simple tasks. Here's the complete code:

即使不应该将流用于如此简单的任务,这也是一个有趣的挑战。这是完整的代码:

public class Example {
    public static void main(String[] args) {
        String[] strings = {"randomText1 randomText2"};
        MyClass myClass = Arrays.stream(strings)
                .map(string -> string.split(" "))
                .flatMap(Arrays::stream)
                .collect(new MyCollector());
        System.out.println("myClass = " + myClass.toString());
    }
}

class MyCollector implements Collector<String, List<String>, MyClass> {
    @Override
    public BiConsumer<List<String>, String> accumulator() {
        return List::add;
    }

    @Override
    public Supplier<List<String>> supplier() {
        return ArrayList::new;
    }

    @Override
    public BinaryOperator<List<String>> combiner() {
        return (strings, strings2) -> {
            strings.addAll(strings2);
            return strings;
        };
    }

    @Override
    public Function<List<String>, MyClass> finisher() {
        return strings -> new MyClass(strings.get(0), strings.get(1));
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Collections.emptySet();
    }
}

class MyClass {
    String s1;
    String s2;

    public MyClass(String s1, String s2) {
        this.s1 = s1;
        this.s2 = s2;
    }

    @Override
    public String toString() {
        return "MyClass{" +
                "s1='" + s1 + '\'' +
                ", s2='" + s2 + '\'' +
                '}';
    }
}