【问题标题】:Reading a .txt file into a 2d arraylist将 .txt 文件读入二维数组列表
【发布时间】:2013-10-25 12:29:05
【问题描述】:

我在 android 中创建一个游戏,其中关卡将存储在单独的 .txt 文件中。每个级别都是一个字符网格,代表地图上的不同项目,但每个级别的大小都不同,所以我想创建一段健壮的代码来读取文件,并将每个级别存储在 2d 中arraylist,不管它的大小是多少。

我的第一次尝试:

private void loadLevel(String filename) {
    mapWidth = 0;
    mapHeight = 0;
    BufferedReader br = null;
    try {
        String line = null;
        br = new BufferedReader(new InputStreamReader(mContext.getAssets().open(filename)));
        while ((line = br.readLine()) != null) {
            mapArray.add(getLevelLine(line));
            mapHeight++;
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null)
                br.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}

private ArrayList<Character> getLevelLine(String line) {
    ArrayList<Character> levelLine = new ArrayList<Character>();
    if (line == null) return levelLine;
    char[] lineArray = line.toCharArray();
    for (char mapPiece : lineArray) {
        levelLine.add(mapPiece);
    }
    mapWidth = lineArray.length;
    return levelLine;
}

这个效率有点低,因为每行都重新计算mapWidth,而且不起作用,因为读取了文本文件的第一横行,并存储在arraylist上的第一纵列,所以它复制了文本文件,但是交换了 x 和 y 坐标。

尝试 2:

    private void loadLevel(String filename) {
    mapWidth = 0;
    mapHeight = 0;
    BufferedReader br = null;
    try {
        String line = null;
        br = new BufferedReader(new InputStreamReader(mContext.getAssets().open(filename)));
        while ((line = br.readLine()) != null) {
            mapArray.add(new ArrayList<Character>());
            char lineArray[] = line.toCharArray();
            for (char mapPiece : lineArray) {
                mapArray.get(mapHeight).add(mapPiece);
            }
            mapHeight++;
            mapWidth = lineArray.length;
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null)
                br.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}

这以同样的方式计算mapWidth,所以看起来还是有点低效。希望通过在数组列表中添加一个空条目,我可以循环遍历它们每个的第 i 个元素。这第二次尝试也没有正确增加mapHeight,因为在最后一次迭代中,mapHeight会增加,然后while循环不会再次执行,但由于某种原因,即使我在while循环之后从mapHeight中减去1,我获取索引越界错误。 更重要的是,通过手动设置mapWidth和mapHeight,我的第二次尝试在将其存储到arraylist时似乎仍然交换了x和y坐标。

我有什么明显的遗漏吗?似乎应该有一种相对简单的方法来做到这一点,不需要预先读取文本文件,并且避免使用普通的 char 数组。

提前感谢您的帮助!

【问题讨论】:

  • 您能否发布输入文件的示例,以及所需结果的示例?您共享的代码解释了您尝试执行的操作,但我仍然不太了解它与您希望执行的操作有何不同。
  • 是的,那太好了……
  • 你的地图总是矩形吗?文本文件中的所有行都具有相同的长度?当涉及到改变 x/y 轴时,我建议将地图包装在一个带有地图单元格吸气剂的类中,这就是为什么你可以在不改变其他任何地方的代码的情况下改变地图的方向。

标签: java android arrays arraylist readfile


【解决方案1】:

我实际上不明白为什么你的第一个例子是你已经切换了行和列。 而且你没有说你正在衡量你的表现。我的意思是什么对您来说更重要 - 速度还是内存消耗?

反正我写了一个示例 input.txt 文件

a b c d e

f g h i g k

l m n o p q r

s t

你v

w

public class ReadTxtArray {
private final static String filePath = "/home/michael/input.txt";
public static void main(String[] args) {
    try (Scanner s = new Scanner(new BufferedReader(new FileReader(filePath)))) {
        List<List<Character>> rows = new ArrayList<List<Character>>();
        while(s.hasNextLine()) {
            rows.add(createRow(s.nextLine()));
        }
        System.out.println(rows);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private static List<Character> createRow(String line) {
    char[] c = line.toCharArray();
    List<Character> chars = Arrays.asList(ArrayUtils.toObject(c));
    return chars;
}

}

[[a, b, c, d, e], [f, g, h, i, g, k], [l, m, n, o, p, q, r, ], [s, t], [u, v], [w]]

这是输出。这是你想要的吗?

我使用 try with resources 块,以防您不熟悉 java 7 功能。很遗憾,它仍然无法在android上使用。真丢人……

【讨论】:

    猜你喜欢
    • 2014-04-06
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多