字符串数组上的 Java 8 流
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34219090/
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
Java 8 streams on string arrays
提问by Lucian Enache
I have a single String of format:
我有一个格式字符串:
row1col1 row1col2
row2col1 row2col2
row3col1 row3col2
and so on...
等等...
I want to extract each item and build an array of objects with properties like this:
我想提取每个项目并构建一个具有如下属性的对象数组:
new MyObject(row1col1, row1col2);
I am new to Java 8 and Streams and I would like to find out how can I achieve this without loops.
我是 Java 8 和 Streams 的新手,我想知道如何在没有循环的情况下实现这一点。
Normally I would use a String.split('\n')for accumulating the rows into an array of String
通常我会使用 aString.split('\n')将行累积到一个字符串数组中
And then a loop where for each line I would split again on the space separator and with the resulting array of the two elements (row1col1 row1col2) build my object, until there are no more rows to process.
然后是一个循环,对于每一行,我将在空格分隔符上再次拆分,并使用两个元素 ( row1col1 row1col2)的结果数组构建我的对象,直到没有更多行要处理。
Like this:
像这样:
String sausage = "row1col1 row1col2\nrow2col1 row2col2\nrow3col1 row3col2";
String[] rows = sausage.split("\n");
for (String row : rows) {
String[] objectData = u.split("\s+");
MyObject myObject = new MyObject(objectData[0], objectData[1]);
myObjectList.add(myObject);
}
Can anyone explain me how to achieve the same with streams and what is the mechanism behind that allows me to do so?
任何人都可以解释我如何使用流实现相同的目标,以及允许我这样做的背后机制是什么?
Is this even a valid way of thinking when increasing the number of elements because from all the examples I've seen the streams focus on filtering, collecting or generally given a set of elements retrieve a minor set applying some criterias.
在增加元素数量时,这是否甚至是一种有效的思维方式,因为从我看到的所有示例中,流都专注于过滤、收集或通常给定一组元素并应用某些标准检索次要集合。
采纳答案by Tunaki
A simple way would be to create a Patternwith the line separator and split the input Stringas a Stream. Then, each line is split with a space (keeping only 2 parts) and mapped to a MyObject. Finally, an array is constructed with the result.
一种简单的方法是Pattern使用行分隔符创建 a并将输入拆分String为Stream. 然后,每行用一个空格分割(只保留 2 部分)并映射到MyObject. 最后,用结果构造一个数组。
public static void main(String[] args) {
String str = "row1col1 row2col2\r\nrow2col1 row2col2\r\nrow3col1 row3col2";
MyObject[] array =
Pattern.compile(System.lineSeparator(), Pattern.LITERAL)
.splitAsStream(str)
.map(s -> s.split("\s+", 2))
.map(a -> new MyObject(a[0], a[1]))
.toArray(MyObject[]::new);
System.out.println(Arrays.toString(array));
}
Using splitAsStreamcan be advantageous over Stream.of(...)if the input Stringis long.
如果输入很长,使用splitAsStream可能会更有优势。Stream.of(...)String
I assumed in the code that the line separator of the Stringwas the default line separator (System.lineSeparator()) of the OS but you can change that if it is not.
我在代码中假设 的行分隔符String是System.lineSeparator()操作系统的默认行分隔符 ( ),但如果不是,您可以更改它。
Instead, if you are reading from a file, you could use Files.lines()to get a hold of a Streamof all the lines in the file:
相反,如果您正在从文件中读取数据,则可以使用Files.lines()来获取Stream文件中所有行的 a :
MyObject[] array = Files.lines(path)
.map(s -> s.split("\s+", 2))
.map(a -> new MyObject(a[0], a[1]))
.toArray(MyObject[]::new);
System.out.println(Arrays.toString(array));
回答by Eran
You could generate a Streamof Strings that represent a single MyObjectinstance, and transform each of them to your MyObjectinstance (by first splitting them again and then constructing a MyObjectinstance) :
您可以生成代表单个实例的a Streamof Strings MyObject,并将它们中的每一个转换为您的MyObject实例(首先再次拆分它们,然后构造一个MyObject实例):
List<MyObject> list =
Stream.of(inputString.split("\n"))
.map (s -> s.split(" "))
.filter (arr -> arr.length == 2) // this validation may not be necessary
// if you are sure each line contains 2 tokens
.map (arr -> new MyObject(arr[0],arr[1]))
.collect(Collectors.toList());

