如何在HashMap中保存大型.txt文件的内容但只显示一行(随机)

时间:2012-12-19 21:54:10

标签: java io hashmap

在Android上创建一个使用RMI和Tomcat的小型战舰游戏。

我需要从文本文件“boards.txt”加载数据,并可能将其存储在HashMap中以便查询。

我无法附加文件,但下面是记事本中.txt文件的屏幕截图。它显示10,000个Battleship游戏板的板布局(我认为无论如何都是这个数字),它是10x10网格。

因此,文件的每100个字符将是不同船只的位置和10 x 10网格的空格,每个网格由换行符分隔。

我正在努力解决的是实际的解析。我认为将数据保存到HashMap将使搜索随机板布局变得更容易。下面是我目前用于读取数据的代码。

public static void main(String[] args) throws FileNotFoundException {
        Scanner scanner = new Scanner(new FileReader("C:\\Path\\boards.txt"));

        HashMap<String, String> map = new HashMap<String, String>();

        while (scanner.hasNextLine()) {
            String columns = scanner.nextLine();
            map.put(columns, columns);
        }

        System.out.println(map);
    }

现在我这样做的主要原因就是摆脱错误。以前我的代码是这样的:

public static void main(String[] args) throws FileNotFoundException {
        Scanner scanner = new Scanner(new FileReader("C:\\Path\\boards.txt"));

        HashMap<String, String> map = new HashMap<String, String>();

        while (scanner.hasNextLine()) {
            String[] columns = scanner.nextLine().split(" ");
            map.put(columns[0], columns[1]);
        }

        System.out.println(map);
    }

但是,我得到了一个超出范围的例外。由于事实上没有空格可以拆分。

好的,我的主要问题是,如何将整个.txt文件保存到HashMap,并且一次只显示一行100个字符。

其次(优先级较低) - 我想随机选择一行,这样我就可以在1-10000之间创建一个随机数来显示一行。我想过使用一个String,Integer HashMap,并且每个行都有一个索引值,但我不知道我会怎么做。

**编辑 对不起,我忘了添加截图。这里是: enter image description here

感谢您的回答,我现在将通读它们

4 个答案:

答案 0 :(得分:2)

直接回答您的问题:

1)你几乎拥有了你的文件阅读器,但你不必费心MapList就足够了。

Scanner scanner = new Scanner(new FileReader("C:\\Path\\boards.txt"));
List<String> lines = new ArrayList<String>();
while (scanner.hasNextLine()) {
    String columns = scanner.nextLine();
    lines.add(columns);
}

2)要抓取随机行,只需在List中选择一个随机索引。

Random random = new Random();
int randomLineIndex = random.nextInt(lines.size());
String randomLine = lines.get(randomLineIndex);

现在,所有这一切,如果您不需要加载整个文件,请不要。如果你只需要从文件中获取一个随机行,那就去吧,保存自己的计算和内存。

为此,您首先需要知道文件中的行数。 This question为您提供:

String file = "C:\\Path\\boards.txt";
BufferedReader reader = new BufferedReader(new FileReader(file));
int lineCount = 0;
while (reader.readLine() != null) lineCount++;
reader.close();

现在您知道有多少行,可以随机选择一行:

Random random = new Random();
int randomLineIndex = random.nextInt(lineCount);

然后你可以抓住那条线并忽略其余部分:

reader = new BufferedReader(new FileReader(file));
int i = 0;
while (++i < randomLineIndex)
    // Skip all lines before the one we want
    reader.readLine();
String randomLine = reader.readLine();

答案 1 :(得分:2)

我就是这样做的。您有最多2 ^ 48种不同的游戏,您可以使用相同的种子重播。这避免了在内存中读取文件或存储索引的需要。您可以根据需要重新创建任何棋盘游戏。

public class Baord {
    private static final int[] SHIP_SIZES = {4, 4, 3, 3, 3, 2, 2, 2, 2,  1, 1};
    public static final char EMPTY = '.';

    private final Random random;
    private final char[][] grid;
    private char letter = 'a';
    private final int width;
    private final int height;

    public Baord(int height,int width,  int seed) {
        this.width = width;
        this.height = height;
        this.random = new Random(seed);
        this.grid = new char[height][width];
        for (char[] chars : grid)
            Arrays.fill(chars, EMPTY);
        for (int len : SHIP_SIZES)
            placeShip(len);
    }

    private void placeShip(int len) {
        OUTER:
        while (true) {
            if (random.nextBoolean()) {
                // across
                int x = random.nextInt(width - len + 1);
                int y = random.nextInt(height);
                for (int j = Math.max(0, y - 1); j < Math.min(height, y + 2); j++)
                    for (int i = Math.max(0, x - 1); i < Math.min(width, x + len + 2); i++)
                        if (grid[j][i] > EMPTY)
                            continue OUTER;
                for (int i = 0; i < len; i++)
                    grid[y][x + i] = letter;

            } else {
                // down
                int y = random.nextInt(height - len + 1);
                int x = random.nextInt(width);
                for (int j = Math.max(0, x - 1); j < Math.min(width, x + 2); j++)
                    for (int i = Math.max(0, y - 1); i < Math.min(height, y + len + 2); i++)
                        if (grid[i][j] > EMPTY)
                            continue OUTER;
                for (int i = 0; i < len; i++)
                    grid[y + i][x] = letter;
            }
            break;
        }
        letter++;
    }

    public String toString() {
        StringBuilder ret = new StringBuilder();
        for (int y = 0; y < grid.length; y++)
            ret.append(new String(grid[y])).append("\n");
        return ret.toString();
    }

    public static void main(String... args) {
        for (int i = 0; i < 3; i++)
            System.out.println(new Baord(8, 16, i));
    }
}

打印

..........ddd...
.....aaaa.......
eee.......j.....
.............i..
..bbbb.......i.c
.......g.......c
.k.h...g...f...c
...h.......f....

ii..............
.....ccc..ff...b
...............b
aaaa...........b
.........j..h..b
....gg......h...
..............k.
eee..ddd........

.d.....eee.....f
.d.............f
.d..............
......j.ccc....g
.............b.g
.............b..
h.i..........b..
h.i...aaaa.k.b..

.......h....aaaa
.......h........
.e.........ccc..
.e..............
.e.bbbb...ii..ff
........d.......
.g..j...d.......
.g......d.....k.

............ccc.
.....bbbb.......
.ii.......k..d..
.....f.......d..
eee..f.......d..
................
.j.g........hh..
...g.aaaa.......

答案 2 :(得分:0)

为什么使用HashMap的密钥和值相同?你所描述的基本上只是一个数组,其中每个桶包含一行100个字符。拉出随机地图意味着创建1-10000之间的随机数并打印该桶的内容。

关于解析,我们需要查看文件本身的示例,以帮助解决您遇到的任何语法问题。

答案 3 :(得分:0)

仅供参考。

scanner.next().split(":");为我工作 scanner.nextLine().split(":");没有。