字符串数组上的Java 8流

时间:2015-12-11 08:29:26

标签: java arrays collections java-8 java-stream

我有一个格式的字符串:

row1col1 row1col2
row2col1 row2col2
row3col1 row3col2

依旧......

我想提取每个项目并构建一个具有以下属性的对象数组:

new MyObject(row1col1, row1col2); 

我是Java 8和Streams的新手,我想知道如何在没有循环的情况下实现这一点。

通常我会使用String.split('\n')将行累积到String

数组中

然后是一个循环,我将在空格分隔符上再次拆分每一行,并使用两个元素的结果数组(row1col1 row1col2)构建我的对象,直到没有更多行要处理。

像这样:

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

任何人都可以向我解释如何使用流来实现相同的目标,这背后的机制是什么让我这样做?

当增加元素数量时,这甚至是一种有效的思维方式,因为从所有的例子中我看到流集中在过滤,收集或通常给出一组元素检索应用一些标准的次要集。

2 个答案:

答案 0 :(得分:11)

一种简单的方法是使用行分隔符创建String,并将输入Stream拆分为MyObject。然后,每行用空格分割(仅保留2个部分)并映射到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)); } 。最后,使用结果构造一个数组。

Stream.of(...)

如果输入String很长,则使用splitAsStream优于String

我在代码中假设System.lineSeparator()的行分隔符是操作系统的默认行分隔符(Files.lines()),但如果不是,则可以更改它。

相反,如果您正在阅读文件,则可以使用Stream来保留文件中所有行的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));

public static class MyClass {

    static MyClass() {
        DoStuff("HardCodedParameter")
    }
}

答案 1 :(得分:5)

您可以生成代表单个Stream实例的StringMyObject,并将每个实例转换为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());