Problema com cópias de matrizes

Olá pessoal,

Estou com um super problema com matrizes:

Estou fazendo um programa onde utilizo várias matrizes [3][3], uma delas é a mais impotante e não posso perdê-la logo tenho que fazer cópias dela para outra matriz. Mas não estou conseguindo fazer isso.

Estou declarando outra matriz auxiliar onde faço:

matriz_auxiliar = matriz_original

mas isso não funciona porque depois que eu faço os testes necessários na matriz auxiliar a matriz original tb muda…

Alguém sabe o que pode estar ocorrendo???

Obrigado pela ajuda

Olá marcosslash,

o que ocorre é que um array/matriz é sempre um objeto em java, e os objetos em java são todos referenciados por suas variáveis.
ou seja, quando você faz


    int matriz_original[10] = {1,2,3,4,5};
    int matriz_auxiliar[10];

    matriz_auxiliar = matriz_original;

você não está copiando os elementos {1,2,3,4,5} mas está copiando o endereço de referência da matriz_original para a variável matriz_auxiliar.

para que funcione você deve fazer da seguinte maneira


     int matriz_original[10] = {1,2,3,4,5};
    int matriz_auxiliar[10];

    System.arraycopy(matriz_original, 0, matriz_auxiliar, 0, matriz_original.length);
   

Isso de modo algum copia o objeto. Ele faz apenas um referência pro mesmo objeto.

Você teria que criar um objeto com as mesmas dimensões e copiar os valores. Ex:

[code]int altura = 1;
int largura = 1;
String[][] a = new String[altura][largura];

String[][] b = new String[altura][largura];
for( int i=0; i<altura; i++ )
for( int j=0; j><largura; j++ )
b[i][j] = a[i][j];
[/code]>

Olha o que minha falta de conhecimento às vezes faz…

Não dá pra usar System.arraycopy() pra arrays multidimensionais, né?

Eu fiz um teste com o método clone(), e ele não funciona como esperado, para arrays de multiplas dimensões.
Aparentemente ele apenas copia as referências dos arrays a partir do array da primeira dimensão.

int[][] a = {{1, 2, 3}, {2, 3, 4}}; int [][] b = (int[][]) a.clone() ; a[1][1] = 100; // altera tanto a como b System.out.println(a == b); // imprime false

Parece que o velho laço “for” não pode ser abandonado quando houver array de arrays.

Em java não existe arrays multidimensionais, o que existem são arrays de arrays…

Você testou isso de não deixar copiar arrays de arrays ou você leu na doc?

[]´s

[quote=Vegetto]Em java não existe arrays multidimensionais, o que existem são arrays de arrays…
[/quote]

http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html#27805

Eu não sei onde tem essa informação, porque não é a primeira vez que eu ouço isso e discordo. Existe alguma bibliografia ou não li algo direito na especificação?

Toda linguagem usa “arrays de arrays”, a menos que exista um modelo de memória com mais de duas dimensões.

Que eu saiba, em C e VB você só pode criar arrays retangulares, ou seja, com dimensões X e Y definidas, diferente do Java que pode variar para cara índice.

Como assim, Destro?

Em C eu posso ter um array de arrays.

Não sei o que você chama de retangular, mas eu possso de ter array de n dimensões em C, java e em qualquer linguagem que conheça, creio.

Como retangular, eu quero dizer que se for uma matriz de duas dimensões, a largura dela é fixa. Explico:

Em C só pode fazer:

int[5][5] i;

Já em Java:

int[][] i = new int[5][];
i[0] = new int[10];
i[1] = new int[3];
i[2] = new int[99];

Nevermind… é sexta-feira.

Em qualquer que seja a linguagem, no final das contas as matrizes vao ficar lineares, pois a memória é linear. Não existe endereço de duas coordenadas.

Acho que o que o pessoal quer dizer é que em Java um array contém outro como se fosse uma lista encadeada, assim como um nó de uma árvore tem referencia para outro nó, sem obrigar o proximo nó a estar “colado” com ele na memoria. Já em C, por exemplo, uma matriz quadrada 2 por 2 era igual a um array de 4 posições. O que a linguagem fazia era facilitar calculando a posição linear por conta propria.

[]'s

Álinson,

è oq eue u acho qeu é pensado também. Mas se nós não estamos falando besteira, isso é falado com muito " :-o " por um simples detalhe de implementação :stuck_out_tongue:

Opa, acabei aprendendo mais uma! :slight_smile:

Como o destro disse eu também conhecia isso do VB… por isso disse que “no java…”

edit: valew pela informação e pelo o link, pcalcaco!! … Eu tinha lido isso em algum lugar(que na hora eu julguei confiável) e, na minha própria experiência, eu acabei “comprovando” isso de “arrays de arrays”…

Valeu danieldestro eu não sabia que o System.arraycopy fazia copia de referências de objetos, obrigado por me corrigir.

Ai galera,não deu muito certo não.

Tentei usar o System.arraycopy não deu nenhum erro mas quando vou executar o projeto ocorre uma exceção e não estou conseguindo arrumar. A exceção que aparece é a seguinte:

Exception in thread “AWT-EventQueue-0” java.lang.ArrayIndexOutOfBoundsException: 3
at subidaencosta.cima(subidaencosta.java:614)
at subidaencosta.EscolheRegra(subidaencosta.java:513)
at subidaencosta.access$6(subidaencosta.java:167)
at subidaencosta$1.actionPerformed(subidaencosta.java:963)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Alguém pode me ajudar a resolver este problema???

Valeu até mais

Oi Marcos… pra matar um ArrayIndexOutOfBoundsExecption, a melhor receita eh usar um bom depurador e acompanhar passo-a-passo o que esta acontecendo, preferencialmente usando um teste unitario (uma classezinha boba com void main() que exercite o problema, sem ter que ficar navegando muito na interface ja esta de bom tamanho, alias). :wink: