Problema com cópias de matrizes

15 respostas
marcosslash

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

15 Respostas

p5f8

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);
danieldestro

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:

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];
>
danieldestro

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

D

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.

V

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

pcalcado

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

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.

danieldestro

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.

pcalcado

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.

danieldestro

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.

iSoron

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

pcalcado

Á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:

V

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”…

p5f8

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

marcosslash

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

cv1

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:

Criado 11 de março de 2005
Ultima resposta 12 de mar. de 2005
Respostas 15
Participantes 8