提取第 n 个字符和另一个第 n 个字符之间的字符串

Extract string between nth character and another nth character

当我试图将游戏的整个地图加载到内存中时,它比我想要的要大一点。我正在尝试将地图分成块。我的游戏地图是逗号分隔的。地图字符串的示例部分:“0, 0, 45, 32, 3, 3, 0, 0,”。

目前我正在使用以下内容,但它需要大约 9 秒(我的地图很大)。

String[] mapArr = map.split(", ");
short[] groundLayer = new short[chunkWidth * chunkHeight];
//code that fills in the groundLayer array

如果玩家在 1 个方向上走得太远,游戏中等待 9 秒将不起作用。

我的想法是做一些事情,其中​​我从逗号 (int firstComma) 到逗号 (int lastComma) 的 'map String' 进行子串。

firstComma = characterX + (characterY * mapWidth);
lastComma = firstComma + (chunkWidth * chunkHeight);

然后我将仅拆分 (", ") 结果子字符串。这是一个明智的性能好主意吗?

做这样的事情最有效的方法是什么?子字符串、正则表达式、indexOf,有什么不同吗?任何帮助将不胜感激。


编辑 在下方提供更多上下文:

我的地图由多层组成,我使用 'Tiled' 到 draw/export 它们。这是我从文件中读取并将它们保存到短数组中的方法。我没有拆分整个映射字符串,而是尝试仅从字符 X 拆分为字符 Y。

try {
    String map = readFile("res/images/tiles/MyFirstMap-building-p.json");
    String[] strArr = map.split(", ");

    buildingLayer = new short[chunkWidth * chunkHeight];
    short arrayIndex = 0;
    for(short y = 0; y < chunkHeight; y++) {
        for(short x = 0; x < chunkWidth; x++) {
            //get the absolute position of the cell
            short cellX = (short) (characterX + x - chunkWidth / 2);
            short cellY = (short) (characterY + y - chunkHeight / 2);
            if(cellX >= 0 && cellX < mapWidth && cellY >= 0 && cellY < mapHeight) { //within bounds
                buildingLayer[arrayIndex] = Short.parseShort(strArr[cellX + (cellY * mapWidth)]);
            } else { //out of bounds, put down a placeholder
                buildingLayer[arrayIndex] = 0;
            }
            arrayIndex++;
        }
    }
} catch (IOException e) {
    logger.fatal("ReadMapFile(building)", e);
    JOptionPane.showMessageDialog(theDesktop, getStringChecked("message_file_locks") + "\n\n" + e.getMessage(), getStringChecked("message_error"), JOptionPane.ERROR_MESSAGE);
    System.exit(1);
}


private static String readFile(String path) throws IOException {
    FileInputStream stream = new FileInputStream(new File(path));
    try {
        FileChannel fc = stream.getChannel();
        MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
        return Charset.defaultCharset().decode(bb).toString();
    }
    finally {
        stream.close();
    }
}

这是我使用的解决方案(为了简单起见,我删除了很多循环逻辑)。感谢@Elliott Frisch 在评论中提供的帮助。

private static short[] scanMapFile(String path, int[] leftChunkSides, int[] rightChunkSides) throws FileNotFoundException {
    Scanner scanner = new Scanner(new File(path));
    scanner.useDelimiter(", ");

    short[] tmpMap = new short[chunkWidth * chunkHeight];
    int count = 0;

    while(scanner.hasNext()){
        tmpMap[count] = scanner.nextShort();    
        count++;
    }

    scanner.close();
    return tmpMap;
}