所以,让我们说我们有一个字符串:" randomText1 randomText2"在数组中,加载到Stream中。
现在我回顾一下这个流中的所有行,并将每一行分成空格字符。
strings
.map(string -> string.split(" "))
.flatMap(Arrays::stream)
.collect(new MyClass(string1, string2));
如何获取字符串的两边并从那里做任何我想要的东西?
从Oracle文档(Oracle doc link)我只能找到一些更难的案例,其中一个人会使用Map<>
。但是我无法使他们的解决方案适应我这个更简单的问题。
答案 0 :(得分:13)
使用flatMap
不适合这项工作。你显然想做的是
strings.map(string -> string.split(" ", 2))
.map(array -> new MyClass(array[0], array[1]))
您可以使用.collect(Collectors.toList())
进一步处理流,以获得List<MyClass>
或.findAny()
来获取单个MyClass
实例(如果有)。
通常,只有当你想要统一处理所有元素时,流式传输数组才有用,例如,如果不是,那么它们的位置具有特殊含义,必须为后续操作保留。
如果如果你真的想要创建一个平坦的单词或代币流,则不应该使用String.split
和Arrays.stream
的组合来创建和填充不必要的中间数组。在这种情况下使用
strings.flatMap(Pattern.compile(" ")::splitAsStream)
答案 1 :(得分:3)
即使不应将流用于此类简单任务,这也是一个有趣的挑战。这是完整的代码:
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 + '\'' +
'}';
}
}