【问题标题】:Reading a file that contains an array with Java使用 Java 读取包含数组的文件
【发布时间】:2018-01-29 09:57:48
【问题描述】:

我正在研究一种机器学习算法,该算法由训练和预测两部分组成,为此我必须将训练结果保存在文件中以便以后使用。 数组是这样声明的:

List<int[][]> samples = new ArrayList<>();

对于我使用的文件:

BufferedWriter writer1 = new BufferedWriter(new FileWriter("results/samples.data"));
writer1.write(Arrays.deepToString(samples.toArray()));
writer1.close(); 

所以该文件包含一个多维数组,如图所示

我已经被困在如何读取它并以正确的形式存储在变量中,并且在大多数情况下搜索解决方案是逐行读取文件,这不是我的情况,因为没有换行符

我在问是否有任何方法可以读取文件,或者是否有比我使用的更好的解决方案。

【问题讨论】:

  • 它看起来像 JSON。使用 JSON 解析器。
  • 如果您不需要将数组以人类可读的格式存储在文件中(以便您可以在文本编辑器中看到它)但很高兴将其以二进制格式存储,请考虑改用 ObjectOutputStream 和 ObjectInputStream。那么你的 I/O 代码会很简单。

标签: java arrays file


【解决方案1】:

给定

[[[1,3][2,5]]
 [[4,8][3,1]]
 [[5,9][6,5]]]

我只会用分隔符存储整数

1 3 ~ 2 5 | 4 8 ~ 3 1 | 5 9 ~ 6 5

使用简单的 for 循环或 lambdas 很容易编写和读取/解析返回

编辑 似乎以这种方式工作:

public static void main(String[] arg) throws Exception {

    // NESTED ARRAYS EXAMPLE
    List<int[][]> nestedlist = Arrays.asList(
        new int[][] { new int[] {1, 3}, new int[] {2, 5} },
        new int[][] { new int[] {4, 8}, new int[] {3, 1} },
        new int[][] { new int[] {5, 9}, new int[] {6, 5} }
    );

    String s = makeStringForNestedArrays(nestedlist);
    System.out.println(s);

    List<Integer[][]> readNestedList = parseStringToNestedArrays(s);
    System.out.println(Arrays.deepToString(readNestedList.toArray()));


    // SIMPLE ARRAYS EXAMPLE
    List<Integer> simpleList = Arrays.asList(1, 3, 5, 6);

    s = makeStringForSimpleList(simpleList);
    System.out.println(s);

    List<Integer> readSimpleList = parseStringToSingleList(s);
    System.out.println(readSimpleList);

  }

  private static String makeStringForSimpleList(List<Integer> list) {
    return list.stream().map(String::valueOf).collect(Collectors.joining(" "));
  }

  private static List<Integer> parseStringToSingleList(String s) {
    return Arrays.stream(s.split(" ")).map(Integer::valueOf).collect(Collectors.toList());
  }

  private static String makeStringForNestedArrays(List<int[][]> list) {
    return list.stream().
        map(arrayOfArrays -> arrayOfArraysToString(arrayOfArrays))
        .collect(Collectors.joining(" | "));
  }

  private static List<Integer[][]> parseStringToNestedArrays(String s) {
    return Arrays.stream(s.split(" \\| "))
        .map(str -> stringToArrayOfArrays(str, " ~ ", " "))
        .collect(Collectors.toList());
  }

  private static String arrayToString(int[] array) {
    return Arrays.stream(array).mapToObj(String::valueOf).collect(Collectors.joining(" "));
  }
  private static String arrayOfArraysToString(int[][] arrayOfArrays) {
    return Arrays.stream(arrayOfArrays).map(array -> arrayToString(array)).collect(Collectors.joining(" ~ "));
  }


  private static Integer[] stringToArray(String s, String delimiter) {
    String[] a = s.split(delimiter);
    return Arrays.stream(a).map(Integer::valueOf).toArray(Integer[]::new);
  }
  private static Integer[][] stringToArrayOfArrays(String s, String delimiterLevel1, String delimiterLevel2) {
    String[] a = s.split(delimiterLevel1);
    return Arrays.stream(a).map(s1 -> stringToArray(s1, delimiterLevel2)).toArray(Integer[][]::new);
  }

【讨论】:

  • 能否请您进行编辑以使该代码还支持具有简单数组的文件,例如[23,15,26,58]
  • 你的意思是用List&lt;int[]&gt; 代替List&lt;int[][]&gt; 吗?
  • 不,我只是希望它同时支持List&lt;int[][]&gt;List&lt;integer&gt;
  • 给你。也有单个列表的示例。
【解决方案2】:

从文件中读取数组的常用方法是在第一行指定数组的长度,然后是 n 行,其中 n 是长度。这样,您就知道分配的数组应该有多大,然后在 for 循环中读取 n 行下一行。对于 2D 数组,只需嵌套这种方法,文件可能看起来像这样:

对于数组:

[[1, 2][3]]

创建一个像这样的文件:

2    // length of the outer array
2    // length of the first inner array
1    // first element of the first array
2    // second element of the second array
1    // size of the second array
3    // first element of the second array

如果您想概括 N 维数组的方法,只需在开头添加一行,指定维度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-07
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    相关资源
    最近更新 更多