从文件中流式传输n个整数列表以创建n个对象数组

mag*_*pie 4 java arrays

假设每个T对象都可以实例化为

T tobj = new T(//int value);
Run Code Online (Sandbox Code Playgroud)

因此,要在由空格分隔的文件中从整数创建T []数组,请执行以下操作:

 BufferedReader br;
 FileReader fr;
 int[] arr;
 try{               
        fr = new FileReader(fo); // assume "fo" file name
        br = new BufferedReader(fr);
        arr = Arrays.stream(br.readLine().split("\\s")).mapToInt(Integer::parseInt).toArray();

 }catch(SomeException e){//something else}

T[] tobjarr = new T[arr.length];
    for(int i=0; i<arr.length; ++i)){
        tobjarr[i] = new T(arr[i]);
    }
Run Code Online (Sandbox Code Playgroud)

1.上述方法在时间和空间使用方面是否有效?

2.还有其他办法吗?如果是这样,它与上述方法相比如何?

Zab*_*uza 5

一般来说,你的方法很好.但是,您可以使用单个流级联来实现.与您的原始方法相比,这可以节省您一次迭代.

另请注意,现在我们使用称为NIO的 Javas新I/O API读取文件.一个很大的优点是它提供了Stream方法.例如Files#lines,在文件的所有行上返回流的方法,非常适合您的方法.

总而言之,这是完整的代码:

String file = ...
Pattern separator = Pattern.compile("\\s");

try (Stream<String> lines = Files.lines(Paths.get(file))) {
    T[] values = lines                      // Stream<String> lines
        .flatMap(separator::splitAsStream)  // Stream<String> words
        .mapToInt(Integer::parseInt)        // IntStream values
        .mapToObj(T::new)                   // Stream<T> valuesAsT
        .toArray(T[]::new);
} catch (IOException e) {
    System.out.println("Something went wrong.");
}
Run Code Online (Sandbox Code Playgroud)

请注意,此代码与您的代码略有不同,因为您的代码只处理一行并挖掘所有行.如果您不需要,可以更改:

List<T[]> valuesPerLine = Files.lines(Paths.get(file))  // Stream<String> lines
    .map(separator::splitAsStream)  // Stream<Stream<String>> wordsPerLine
    .map(lineStream -> {
        return lineStream                 // Stream<String> words
            .mapToInt(Integer::parseInt)  // IntStream values
            .mapToObj(T::new)             // Stream<T> valuesAsT
            .toArray(T[]::new);
    })                              // Stream<T[]> valuesPerLine
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

与原始方法的主要区别在于,我们可以通过使用(或者只是它是常规流而不是)将元素传递给构造函数来轻松地将其IntStream转换为a .之后我们通过使用收集到一个数组.Stream<T>mapToObj(T::new)mapIntStreamStream<T>toArray(T[]::new)

  • 最好使用[尝试使用资源](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html): (2认同)
  • @FedericoPeraltaSchaffner谢谢,我认为`Files#lines`是这样做的.但显然它没有:[为什么Files.lines(和类似的Streams)不会自动关闭?](/sf/ask/2385042481/ - 自动封闭) (2认同)