在一个列表中更改值会使其单独更改

时间:2016-10-13 08:52:14

标签: java list

我正在尝试将数组normMap中的值更改为另一个,但这样做也会更改数组fireMap中的值。

public int boardX = Board.boardX;
public int boardY = Board.boardY;
public int tileSizeX = Board.tileSizeX;
public int tileSizeY = Board.tileSizeY;
public int curr_dimension = Board.current_dimension;

public BufferedImage[] grassImage = {Board.norm.grassImage, Board.fire.grassImage};
public BufferedImage[] waterImage = {Board.norm.waterImage, Board.fire.waterImage};
public BufferedImage[] pathVImage = {Board.norm.pathVImage, Board.fire.pathVImage};
public BufferedImage[] pathHImage = {Board.norm.pathHImage, Board.fire.pathHImage};
public BufferedImage[] treeImage =  {Board.norm.treeImage, Board.fire.treeImage};

// y/x/tile type
public List<List<Integer>> normMap = new ArrayList<List<Integer>>();
public List<List<Integer>> fireMap = new ArrayList<List<Integer>>();

@Override
public void mouseClicked(MouseEvent arg0) 
{
    int y = (int) Math.ceil((arg0.getY() + boardY * tileSizeY) / 32);
    int x = (int) Math.ceil((arg0.getX() + boardX * tileSizeX) / 32);
    switch(curr_dimension)
    {
    case(0): normMap.get(y).set(x, 0); break;
    case(1): fireMap.get(y).set(x, 0); break;
    }
}

@Override
public void keyPressed(KeyEvent arg0) 
{
    switch(arg0.getKeyCode())
    {
    case(KeyEvent.VK_ENTER): writeFile(); break;
    case(KeyEvent.VK_ESCAPE): GameStateManager.setState(GameStateManager.MENU_STATE); break;
    case(KeyEvent.VK_UP): boardY--; break;
    case(KeyEvent.VK_DOWN): boardY++; break;
    case(KeyEvent.VK_LEFT): boardX--; break;
    case(KeyEvent.VK_RIGHT): boardX++; break;
    case(KeyEvent.VK_1): curr_dimension = 0; break;
    case(KeyEvent.VK_2): curr_dimension = 1; break;
    }

}

public String getPrefix(int dimension)
{
    switch(dimension)
    {
    case(0): return "norm";
    case(1): return "fire";
    default: 
        System.out.println("Incorrect dimension, " 
    + dimension + ". Find the map in maps/custom/unidentified."); 
        return "unidentified";
    }
}

public void writeFile()
{
    List<List<Integer>> map;

    switch(curr_dimension)
    {
    case(0): map = normMap; break;
    case(1): map = fireMap; break;
    default: map = normMap; break;
    }
    PrintWriter writer;
    try 
    {
        for(int i = 0; i < 2; i++)
        {
            writer = new PrintWriter("/maps/custom/" + getPrefix(i) + "map1.txt", "UTF-8");
            for(List<Integer> list : map)
            {
                for(int integer : list)
                {
                    writer.print(integer + " ");
                }
                writer.println("");
            }
            writer.close();
        }
    }
    catch (Exception e) 
    {
        e.printStackTrace();
    }
}

@Override
public void init() 
{
    Main.panel.addKeyListener(this);
    Main.panel.addMouseListener(this);

    for(int i = 0; i < 50; i++)
    {
        List<Integer> map1 = new ArrayList<Integer>();
        for(int j = 0; j < 50; j++)
        {
            map1.add(9);
        }
        normMap.add(map1);
        fireMap.add(map1);
    }
}

public void draw(Graphics g)
{
    switch(curr_dimension)
    {
    case(0): drawTiles(g, normMap); break;
    case(1): drawTiles(g, fireMap); break;
    }

}

public void drawTiles(Graphics g, List<List<Integer>> map)
{
    for(int y = 0; y < map.size(); y++)
    {
        List<Integer> mapY = map.get(y);
        for(int x = 0; x < mapY.size(); x++)
        {
            if(mapY.get(x) == 0) g.drawImage(grassImage[curr_dimension], (x - boardX) * tileSizeX, (y - boardY) * tileSizeY, null);
            else if(mapY.get(x) == 1) g.drawImage(waterImage[curr_dimension], (x - boardX) * tileSizeX, (y - boardY) * tileSizeY, null);
            else if(mapY.get(x) == 2) g.drawImage(pathVImage[curr_dimension], (x - boardX) * tileSizeX, (y - boardY) * tileSizeY, null);
            else if(mapY.get(x) == 4) g.drawImage(pathHImage[curr_dimension], (x - boardX) * tileSizeX, (y - boardY) * tileSizeY, null);
            else if(mapY.get(x) == 3) g.drawImage(treeImage[curr_dimension], (x - boardX) * tileSizeX, (y - boardY) * tileSizeY - tileSizeY, null);
            else if(mapY.get(x) == 9) g.drawRect((x - boardX) * tileSizeX, (y - boardY) * tileSizeY, tileSizeX, tileSizeY);
            else if(mapY.get(x) == Board.PLAYER) GameState.player.draw(g, x, y, boardX, boardY, tileSizeX, tileSizeY);

        }
    }
}}

预期输出是两个不同的列表。但是,打印出fireMap和normMap会显示相同的结果。

删除了不重要的代码段。请告诉我是否需要澄清任何事情。

1 个答案:

答案 0 :(得分:1)

您可以在此处将相同的对象添加到NormMap和FireMap中:

    normMap.add(map1);
    fireMap.add(map1);

即使两张地图不同,地图内的对象也是一样的。因为在两个映射中都有相同的对象normMap.get(y)和fireMap.get(y)也是一样的,如果你这样做了

normMap.get(y).set(x, 0);

你也改变了fireMap对象。所以你的问题是,你有两个不同的地图,但地图中的所有对象都是相同的。

在我的意见中,解决问题的最简单方法是向地图添加两个不同的对象:

for(int i = 0; i < 50; i++)
{
    List<Integer> map1 = new ArrayList<Integer>();
    List<Integer> map2 = new ArrayList<Integer>();
    for(int j = 0; j < 50; j++)
    {
        map1.add(9);
        map2.add(9);
    }
    normMap.add(map1);
    fireMap.add(map2);
}

编辑:如果您的列表具有适合的尺寸(50 x 50)并且您永远不会更改该尺寸,我建议您使用二维数组

int fireMap[][] = new int[50][50];

(另外:在游戏中,平铺贴图通常是2-D阵列)