Duvida array Bidimensional.....java.lang.ArrayIndexOutOfBoundsException: 2

Olá,

não estou visualizando erro ao tentar carregar por coluna …

se alguém puder me ajudar …

abs

	int [][] array1 = new int [2][3];
		    for ( int i = 0; i < array1.length; i++ ) {  
			        for ( int j = 0; j < array1[i].length; j++ ) {  
			            // por linha  
			            array1[i][j]=  (int) Math.random();  
			        }  
			    }  
			      
			    for ( int i = 0; i < array1[i].length; i++ ) { 
			    	System.out.println("i="+i);
			       for ( int j = 0; j < array1.length; j++ ) { 
			    	   System.out.println("j="+j);
			           // por coluna  
			           array1[j][i]=(int) Math.random();  
			       }  
			   }  
	}
i=0
j=0
j=1
i=1
j=0
j=1
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
	at revisao.array.Bidimensional.main(Bidimensional.java:19)


for ( int i = 0; i < array1[i].length; i++ ) { System.out.println("i="+i); for ( int j = 0; j < array1.length; j++ ) { System.out.println("j="+j); // por coluna array1[j][i]=(int) Math.random(); } }
Na última comparação do for o i passa pra 2, quando ele compara com o array[2].length da erro mesmo.
O vetor só possui 2 linhas (0 e 1).

Ou seja, no segundo for você está invertendo as posições de linha e coluna… daí excede a capacidade da matriz…

Pessoal… vejam lá se me conseguem ajudar nisto…

(…)

    public void distribuirBarcos (Tabuleiro tabDimensionado, int nj, int barco, int direccao)
    {
        if(barco==1) //porta-avioes
        {
            if(direccao==1) //virado para cima
            {
                //gerar linha aleatoriamente
                int l = geraAleatorio(tabDimensionado.getBiDimensao());
                //gerar uma coluna aleatoriamente
                int c = geraAleatorio(tabDimensionado.getBiDimensao());
                tabDimensionado[l][c]=new Casa(); //ESTÁ A DAR ERRO AQUI!!

            }
            else if(direccao==2) //virado para baixo
            {

            }
            else if(direccao==3) //virado para a esquerda
            {

            }
            else if(direccao==4) //virado para a direita
            {

            }

        }

    }

(...)

O erro é onde aparece comentado “//O erro está aqui” e a msg que dá é: array required, but projcetobn.Tabuleiro found … tipo… ele quer o array e encontra o tabuleiro… mas eu no construtor do Tabuleiro não devolvo o array?? Ou isto nao se pode fazer assim… se me puderem ajudar… Não gosto nada de arrays bidimensionais… nem percebo nada como já podem ter reparado… :frowning:

Já agr para estarem por dentro… o que eu kero fazer é pegar na casa que resulta do cruzamento da linha (l) e coluna © do tabuleiro e preencher essa casa com determinados dados.

Vou por aqui a classe Casa e Tabuleiro para vcs verem se o erro está nessas classes:

public class Casa
{
    private int linha;
    private int coluna;
    private boolean visibilidade;
    private String ocupacao;

    //construtures
    //ainda ver qual e com que parâmetros vou necessitar
    public Casa()
    {
    }

    public Casa(int linha, int coluna, boolean visibilidade, String ocupacao)
    {
        this.linha = linha;
        this.coluna = coluna;
        this.visibilidade = visibilidade;
        this.ocupacao="nd";

    }
}
public class Tabuleiro
{
    private Casa[][] tabDimensao;
    private int biDimensao;

    public Tabuleiro()
    {
    }

    public Tabuleiro(int biDimensao)
    {
        this.tabDimensao = new Casa[biDimensao][biDimensao];
        this.biDimensao = biDimensao;
    }

    public int getBiDimensao()
    {
        return biDimensao;
    }

    public void setTabDimensionado(Casa[][] tabDimensao)
    {
        this.tabDimensao = tabDimensao;
    }
}

Bem, nao sei se estou certo mas pelo o que eu entendi você ta querendo atribuir
uma Casa() a variavel de instancia tabDimensao localizada na classe Tabuleiro, certo?

Porque do jeito que você colocou na linha 11:

está tentando adicionar um objeto Casa() à um objeto tabDimensionado…

Outra, um construtor não retorna nada, lembre-se uma das caracteristica de construtores
é: eles não tem retorno.

O que você está fazendo no construtor é inicializar a variavel de instancia "tabDimensao"
localizada na classe Tabuleiro. E também, para de fato inicializar esta variavel você tem
que instanciar um objeto assim:

Tabuleiro tab = new Tabuleiro(1); // criei um objeto tabuleiro, usando o construtor // sobrecarregado da classe Tabuleiro. Esse objeto também // inicializa duas variaveis: biDimensao, neste caso = 1, // e tabDimensao, um array bidimensional de tipo Casa() // com 1 de tamanho.

A partir daí, para ter acesso ao array instanciado quando você cria um objeto Tabuleiro(), você
vai precisar criar algum método que retorne este array, porque no código que você postou a
variavel é privada e não tem um método “Casa[][] getTabDimensao() { return tabDimensao }”, quero dizer,
nenhum método “get()” que retorne o array. No código somente existe um método que retorna o tamanho
do array.

Outra, aqui você coloca:

int l = geraAleatorio(tabDimensionado.getBiDimensao()); // aqui eu sugiro que você use somente uma variavel.
int c = geraAleatorio(tabDimensionado.getBiDimensao()); // porque pelo o que eu vi a o array bidimensional que
							// você criou tem as duas dimensões com o mesmo tamanho.

Ok, então após criar o metódo “getTabDimensao()” na classe Tabuleiro você vai poder dizer:

Casa[][] casa = tabDimensionado.getTabDimensao();
casa[?][?] = new Casa(); // ? vai depender do tamanho do array quando o objeto foi instanciado:
                                     //  "new Tabuleiro(5);" ? < 5

Eu sou somente um estudante de Java, não tenho nada além de horas de estudo, então se eu me equivoquei
em alguma coisa alguém me corrija por favor =).
Espero ter ajudado!

Vlws!

edit: acho que fui um pouco além…

Bem, pelo o que vi você errou em dizer que ao criar um objeto Tabuleiro a variavel tabDimensionado (receberia um array bidimensional), o que não é verdade. Acho que tudo que escrevi pode ser resumido em:
Construtores não retornam nada.
Faça um metodo get() que retornará o seu array bidimensional que ai você poderá ter acesso a ele.

Na verdade é simples!

Veja o que você está fazendo…

// Existe esse atributo recebido pelo método. Tabuleiro tabDimensionado // Então você gera duas coordenadas (tipo x e y): int l = geraAleatorio(tabDimensionado.getBiDimensao()); int c = geraAleatorio(tabDimensionado.getBiDimensao()); // Você está tentando fazer isso: tabDimensionado[l][c]=new Casa()
Tem várias coisas erradas aqui, Mas é falta de conhecimento e prática com os conceitos envolvidos! Vamos por partes…

tabDimensionado é um objeto do tipo Tabuleiro.

Pra começar esse objeto não é uma matriz!

Seria uma matriz se fosse alguma coisa assim:

Nesse caso você teria instanciado uma matriz de tabuleiros com 8 x 8 posições nulas, e em cada posição poderia adicionar uma nova instância de Tabuleiro:

for(int y=0; y<tabDimensionado.length; y++) { for(int x=0; x<tabDimensionado[y].length; y++) { tabDimensionado[y][x] = new Tabuleiro(); } }

MAS logicamente isso não me parece fazer sentido, você deve querer uma matriz de casas no seu tabuleiro, não uma matriz de tabuleiros!

A sua classe Tabuleiro possui uma matriz de casas? Tipo…

public class Tabuleiro { private Casa[][] casas; // construtores, getters, setters, etc... }
Nesse caso você acessaria o atributo casas (uma matriz de objetos do tipo Casa inicialmente nula e após instanciada com as posições nulas) pelos getters e setters, e ficaria com alguma coisa assim:

tabDimensionado.setCasas(new Casa[8][8]); for(int y=0; y<tabDimensionado.getCasas().length; y++) { for(int x=0; x<tabDimensionado.getCasas()[y].length; x++) { // Entenda essa parte: tabDimensionado.getCasas()[y][x] = new Casa(); } }
Ou mais fácil:

Tabuleiro tab = new Tabuleiro(); Casa[][] casas = new Casa[8][8]; for(int y=0; y<casas.length; y++) { for(int x=0; x<casas[y].length; x++) { // Entenda essa parte: casas[y][x] = new Casa(); } } // Entenda essa parte: tab.setCasas(casas); }
Agora sim, veja que eu tenho um objeto tabDimensionado do tipo Tabuleiro, esse objeto contém uma matriz Casa[][] que é uma matriz, não um objeto do tipo Casa. Essa matriz pode ser instanciada com largura e altura x e y, ficando inicalmente com as posições nulas, e pode receber em cada posição uma nova instância (um novo objeto) do tipo Casa: new Casa();

Quando eu fiz a federal de Ciência da Computação, eu tinha um professor de mil quinhentos e guaraná com rolha que era muito enfático em dizer: é importante conhecer os conceitos antes de pensar em programar. Senão não dá pra saber o que se está fazendo.

Orientação a objetos pode parecer uma coisa muito confusa no começo, mas todo novo paradigma é um mistério até que a gente estude melhor. Programação orientada a objetos tem seus blocos “procedurais”, mas o conceito da orientação a objetos é fundamental, e não é intuitivo nem automático para quem programa procedural, mas eu te garanto que uma vez que você estude esse conceito cuidadosamente em breve você vai entender e dominar essa programação.

Não tenha medo da linguagem e não desista, você só vai dominá-la com paciência e persistência, e pode ir tão longe quanto quiser. Veja:

Tabuleiro é uma classe, é um tipo, uma “forma de prensa” de fábrica para “prensar” vários objetos do tipo tabuleiro (ou só um se você só precisar de um).

new Tabuleiro() é uma ordem para que seja “prensado” um novo objeto com as características da forma Tabuleiro.

Eu posso atribuir essa nova instância a uma variável do tipo Tabuleiro:

Tabuleiro tab1 = new Tabuleiro();

Agora tab1 referencia esse novo objeto prensado na forma da classe Tabuleiro.

Essa classe pode conter outras classes, por exemplo uma Casa:

Casa c = new Casa();

Mas isso é uma casa (um objeto prensado na forma da classe Casa), e não tem nada a ver com um vetor ou uma matriz de casas, que é um conjunto de posições vazias que podem ser preenchidas com novos objetos prensados na forma da classe Casa, assim:

[code]public class Tabuleiro { // Uma classe para criar objetos do tipo Tabuleiro
private Casa[][] casas = new Casa[][]{ // Uma nova matriz para objetos do tipo Casa
{new Casa(), new Casa()}, // Duas novas casas na primeira linha
{new Casa(), null}, // Uma nova casa e uma posição vazia na segunda linha
{null, new Casa()} // Uma posição vazia e uma nova casa na terceira linha
};

public Casa[][] getCasas() {
	return casas;
}

public void setCasas(Casa[][] casas) {
	this.casas = casas;
}

}[/code]
Nesse exemplo eu já instanciei a matriz de casas no momento da declaração, ou seja, eu já criei a variável e já atribuí valores a ela.

Depois forneci um método get e outro método set para permitir acesso a essa matriz de casas, obtendo os seus valores ou setando uma nova matriz.

Existem muitos jeitos de fazer essas instâncias (como eu fiz acima, no momento da declaração), várias sintaxes possíveis, eu procurei escolher uma sintaxe didática.

Mas o importante é fixar esses conceitos, e com a prática você poderá compreendê-los de forma cada vez mais transparente facilitando muito a sua codificação.

Outros conceitos importantes são os construtores, getters, setters, classes abstratas, interfaces, sobrecarga e sobrescrição de métodos, herança, polimorfismo, como usar collections…

Quanto tempo você leva pra aprender depende só da sua vontade, se você estiver motivado pode ler o Deitel todo em uma semana, fazendo os exercícios, e você vai ver como vai chegar um momento em que vai ficar muito fácil criar o que você quiser com Java!

:wink:

Boa sorte!

Obrigado aos dois Posts.

Eu sou de portugal… e acabei de acordar… já li na diagonal as explicações… mas vou ler melhor daqui a 2 horas, que eu agora vou para a faculdade pq tenho uma aula.

Só queria deixar aqui uma pergunta…

Tanto num como noutro post, vcs dizem que eu preciso de um array de casas, na classe tabuleiro… e isso eu tenho.
O nome nao é muito elucidativo, mas é aquele que diz…

private Casa[][] tabDimensao;

Outra coisa… o atributo tabDimensionado que eu utilizo (recebido por parâmetro) no método que me dá o erro… é o que resulta ("tab"do metodo que está ai em baixo e que eu nao pus no post inicial… pq ja estava a pôr tanto código que depois achei que ficava confuso.

public Tabuleiro escolherTab()
    {
        boolean flag=true;

        while(flag)
        {
            //Menu para escolher o tabuleiro
            System.out.println("=====================");
            System.out.println("======TABULEIROS=====");
            System.out.println("=====================");
            System.out.println();
            System.out.println("1 - Tabuleiro 10 x 10");
            System.out.println("2 - Tabuleiro 12 x 12");
            System.out.println("3 - Tabuleiro 16 x 16");
            System.out.println("4 - Ajuda");
            System.out.println("5 - Sair");
            System.out.println();
            System.out.println("Escolha uma opção: ");

            //criar a variável que recebe a opção do utilizador
            int opcaoTab = leTeclado.nextInt();

            if(opcaoTab==1)
            {
                //tamanhoTab=10;
                flag=false;
                tab = new Tabuleiro(10);
                memTabuleiro = "10 x 10";
            }
            else if(opcaoTab==2)
            {
                //tamanhoTab=12;
                flag=false;
                tab = new Tabuleiro(12);
                memTabuleiro = "12 x 12";
            }
            else if(opcaoTab==3)
            {
                //tamanhoTab=16;
                flag=false;
                tab = new Tabuleiro(16);
                memTabuleiro = "16 x 16";
            }
            else if(opcaoTab==4)
            {
                flag=false;
                ajudaTab();
            }
            else if(opcaoTab==5)
            {
                flag=false;
                System.out.println("Tem a certeza que quer sair? (s/n)");
                String opcaoSair = leTeclado.nextLine();
                if(opcaoSair.equals("s"))
                {
                    System.exit(0);
                }
                else
                {
                    System.out.println("Bem me parecia.. ");
                    System.out.println();
                    flag=true; //isto é.. nao sai do ciclo e volta a mostrar o menu;
                }
            }
            else
            {
                flag=true;
                System.out.println("Opção Inválida. Introduza a opção correcta!");
            }
        }
        return tab;
    }

Neste metodo eu só queria que o utilizador assim que escolhesse uma opção… eu conseguisse criar um tabuleiro com aquela bi dimensao escolhida… isto é… chamo um construtor da classe Tabuleiro, especifico para esss casos… (sé recebe um inteiro) que cria um array bidimensional (o tal atributo tabDimensao).

Mas pronto… de certeza que estou a fazer confusao, vou ler tudo mais ao promenor daqui a bocadinho.

Obrigado por tudo pessoal.