GARANTIR DESCONTO

Fórum Como fazer ArrayList bidimensional? #565893

15/07/2013

0

Olá, Estou fazendo um jogo do tipo "warcraft"/"age of empires" e tenho que gerenciar a posição das unidades(objeto Unidade) nas cordenadas X e Y. Pensei em usar um ArrayList bidimensional, onde as cordenadas seriam os indices, mas eu não sei como fazer isso, alguem poderia me mostrar como iniciar, ler e regravar um array assim? LEMBRANDO que eu quero armazenar no ArrayList SOMENTE as unidades ativas...cordenadas vazias serão ignoradas já que a area é muito grande(por isso não posso usar arrays normal de tamanho fixo). Obrigado.
Daniel Gimenes

Daniel Gimenes

Responder

Post mais votado

16/07/2013

Parando pra pensar, acredito que seja mais otimizado você utilizar dois Maps ao invés de duas Lists. Criei uma classe que implementa a funcionalidade de uma matriz bidimensional, vejá só: Código de teste:
public class Teste {

    public static void main(String[] args) {
    	// criando uma matriz dinâmica de String, poderia ser de qualquer outra coisa
        MatrizDinamica<String> matriz = new MatrizDinamica<String>();

        int linhas = 10;
        int colunas = 5;

        for (int i = 0; i < linhas; i++) {
            for (int j = 0; j < colunas; j++) {
                String elemento = "linha: " + i + ", coluna: " + j;
                matriz.set(i, j, elemento); // inserindo o elemento
            }
        }

        for (int i = 0; i < linhas; i++) {
            for (int j = 0; j < colunas; j++) {
                String elemento = matriz.get(i, j); // obtendo o elementos
                System.out.println(elemento);
            }
        }

    }
}
Agora a implementação da matriz dinamica:
import java.util.*;

public class MatrizDinamica<T> {

    private final Map<Integer, Map<Integer, T>> elementos = new HashMap<Integer, Map<Integer, T>>();

    public void set(int linha, int coluna, T elemento) {
        Map<Integer, T> colunas = getColunas(linha);
        Integer chave = Integer.valueOf(coluna);
        if (elemento != null) {
            colunas.put(chave, elemento);
        } else {
            colunas.remove(chave);
        }
    }

    public T get(int linha, int coluna) {
    	Map<Integer, T> colunas = getColunas(linha);
        Integer chave = Integer.valueOf(coluna);
        T elemento = colunas.get(chave);
        return elemento;
    }

    private Map<Integer, T> getColunas(int linha) {
        int chave = Integer.valueOf(linha);
        Map<Integer, T> colunas = elementos.get(chave);
        if (colunas == null) {
            colunas = new HashMap<Integer, T>();
            elementos.put(chave, colunas);
        }
        return colunas;
    }
}

Ricardo Staroski

Ricardo Staroski
Responder

Gostei + 1

Mais Posts

15/07/2013

Ricardo Staroski

Assim como um array bi-dimensional nada mais é do que um array de arrays, uma lista bidimensional pode ser representada por uma lista de listas:
List<List<TipoDeDado>> listaDeListas = new ArrayList<List<TipoDeDado>>();
Responder

Gostei + 0

15/07/2013

Thiago Palmeira

Veja esse artigo, talvez possa te ajudar... https://www.devmedia.com.br/trabalhando-com-arrays-em-java/25530
Responder

Gostei + 0

17/07/2013

Daniel Gimenes

[quote="staroski"]Parando pra pensar, acredito que seja mais otimizado você utilizar dois Maps ao invés de duas Lists.
Cara nossa, valew, ajudou muito...só uma duvida, pq o hashmap é melhor que o arraylist neste caso especifico? Ah...e desculpe a ignorancia em hashmap, nunca tinha usado...como faço para destruir um elemento? E para mover um elemento para outro indice? Valew
Responder

Gostei + 0

17/07/2013

Ricardo Staroski

A diferença entre um List e um Map é que um List guarda seus elementos em índices e um Map utiliza chaves. No seu caso, as chaves vão ser o número da linha num Map e o número da coluna em outro Map. Para remover um elemento você utiliza o método remove, se você olhar a implementação que fiz, isso acontece no método set da classe MatrizDinamica, se tu setar um elemento como null, o elemento que estava naquela coordenada, vai ser removido. Se você quisesse usar List teria que ter uma estrutura de dados propria pra poder mapear a linha e coluna do objeto inserido, daria um trabalhão, imagina que sua lista tenha 10 elementos e você quer inserir um na posição 20, terias que inserir 9 elementos dummy para poder aí inserir no índice 20 o objeto que você quer. Com o Map não acontece isso, o Map não é uma lista encadeada, ele é um par chave-valor.
Responder

Gostei + 0

17/07/2013

Thiago Palmeira

Bacana muito bem bolado o código...
Responder

Gostei + 0

17/07/2013

Leonardo Oliveira

Monstruoso esse codigo!!!
Responder

Gostei + 0

17/07/2013

Ricardo Staroski

[quote="leonardooliveira"]Monstruoso esse codigo!!!
Monstruoso porque? Não vejo monstruosidade em um método set para setar o elemento numa posição e um método get para obter o elemento de determinada posição...
Responder

Gostei + 0

22/10/2014

Carlos Rocha

Estou com uma dúvida que talvez possam me ajudar. Imagine a cena de um ArrayList de ArrayList de inteiros da forma abaixo 1 -> [3,1,8,9] ArrayList 2 -> [10,2,4,5] 3 -> [9,3,4,5,5,9,0] Como faço para remover apenas um índice do arrayList[2]. No caso a posição 0 que representa o número 10. Tentei da duas formas abaixo: listaRepetida2[conta[i]].remove(conta[i+1]); listaRepetida2[conta[i]].remove(conta[i+1]); e.... listaRepetida2.get(conta.get(i)).remove(conta.get(i+1)); listaRepetida2.get(conta.get(i)).remove(conta.get(i+1)); Mas nenhuma delas funcionou. No caso elas estão em um loop de um ArrayList de inteiros que retorna apenas 1 posição com [1,0,1] for (int i = 0; i < conta.size(); i++) { listaRepetida2[conta[i]].remove(conta[i+1]); listaRepetida2[conta[i]].remove(conta[i+1]); /* listaRepetida2.get(conta.get(i)).remove(conta.get(i+1)); listaRepetida2.get(conta.get(i)).remove(conta.get(i+1)); */ i+=2; } Pode me ajudar? Desde já obrigado! Carlos Rocha
Responder

Gostei + 0

22/10/2014

Ricardo Staroski

Posta o código completo de seu fonte e explique com clareza o que você quer fazer. Se você quer remover elementos de uma lista que está dentro de outra, o caminho é esse:
List listaInterna = listaExterna.get( posicaoDaListaQueQueroAcessar );
listaInterna.remove( posicaoDoElementoQueQueroRemoverDaListaInterna );
Responder

Gostei + 0

22/10/2014

Carlos Rocha

Ok. Me perdoe por ter duplicado o post. Isso não mais se repetirá. É o seguinte: Tenho a classe abaixo que tem um atributo que é um Array<Array<Integer>>. Nela, tenho um método que trata de ver se nesses arrays existe alguma sequencia de 2 pontos que se repetem e excluilos.
import java.util.ArrayList;

public class RemoveRepetidas
{
  ArrayList<ArrayList<Integer>> listaRepetida = new ArrayList<ArrayList<Integer>>();
  
  RemoveRepetidas (ArrayList<ArrayList<Integer>> _listaRepetida)
  {
    this.listaRepetida = _listaRepetida;	
  }
  
    	
  String removeRepetida()
  {      
		 System.out.println(this.listaRepetida);
		 ArrayList<Integer> conta = new ArrayList<Integer>();		  
         ArrayList<ArrayList<Integer>> listaRepetida2 = listaRepetida;
	       
		   
		   for (int i = 0; i < listaRepetida2.size(); i++)
		   {				 
  		      for (int j = i+1; j < listaRepetida2.size(); j++)
		      {			  
         		   for (int k = 0; k < listaRepetida2.get(i).size(); k++)
		           {	
  		               for (int l = 0; l < listaRepetida2.get(j).size(); l++)
		               {		
				           if (
				                ( listaRepetida2.get(i).get(k) == listaRepetida2.get(j).get(l) && listaRepetida2.get(i).get(k+1) == listaRepetida2.get(j).get(l+1) ) ||
					            ( listaRepetida2.get(i).get(k+1) == listaRepetida2.get(j).get(l) && listaRepetida2.get(i).get(k) == listaRepetida2.get(j).get(l+1) )
					          )
					          {
								  conta.add(j);
								  conta.add(l);
					          } 
							  
				              l++;
			           }
					   
			           k++;
		           } 
			  }
	        }
			
		    for (int i = 0; i < conta.size(); i++)
			{		
                          // NÃO ESTA REMOVENDO
			  listaRepetida2.get(conta.get(i)).remove(conta.get(i+1));
			  listaRepetida2.get(conta.get(i)).remove(conta.get(i+1));

			  i+=2;
			}
			
		   String texto = "{";
           texto += "}";
	
		   System.out.println(listaRepetida2);
		   
		   return texto;
  }
}
O Array Conta traz 2 indices. 1 -> O index do Array Pai 2 -> O index do Array Filho que será removido A primeira volta do ArrayList conta me traz: [1,0,1] Que quer dizer, retirar do indice 1 do array pai, os indices 0 e 1 do seu filho
Responder

Gostei + 0

22/10/2014

Carlos Rocha

Veja o que eu percebi:
		    for (int i = 0; i < conta.size(); i++)
			{
			  System.out.println(conta.get(i+1)); // isso retorna 0
			  System.out.println(conta.get(i+2)); // isso retorna 1
			  
			  listaRepetida2.get(conta.get(i)).remove(conta.get(i+1));
			  listaRepetida2.get(conta.get(i)).remove(conta.get(i+2));
			  
			  i+=2;
			}
Se eu fizer
	  listaRepetida2.get(conta.get(i)).remove(0);
	  listaRepetida2.get(conta.get(i)).remove(1);
Funciona. Mas se fizer
	  listaRepetida2.get(conta.get(i)).remove(conta.get(i+1));
	  listaRepetida2.get(conta.get(i)).remove(conta.get(i+2));
Não funciona. Porque será?
Responder

Gostei + 0

22/10/2014

Carlos Rocha

Consegui. Agora estou tendo o seguinte retorno, é uma String:
C:\java\AD2\java>java Principal
{1,3,3,2,,1,4,,}

C:\java\AD2\java>
Preciso transformar em:
C:\java\AD2\java>java Principal
{1,3,3,2,1,4}

C:\java\AD2\java>
Tentei:
  texto.replaceAll(",,",",");
  System.out.println(texto);
e não funcionou.
Responder

Gostei + 0

22/10/2014

Ricardo Staroski

Se você olhar a documentação da interface List, vai perceber que existem dois métodos [b]remove[/b]: - um que espera como parâmetro um [b]tipo primitivo int[/b], correspondente à posição que você quer remover - outro que espera o [b]objeto[/b] a ser removido da lista, independente de sua posição O Java Collections Framework não suporta tipos primitivos, assim, o método [b]get(posicao)[/b] da interface List sempre retorna um [b]objeto[/b]. O código que você escreveu equivale a isso aqui:
// posicao1 é do tipo objeto Integer e não tipo primitivo int
Integer posicao1 = conta.get(i);

// posicao2 também é do tipo objeto Integer e não tipo primitivo int
Integer posicao2 = conta.get(i + 1);

// o método get espera receber um tipo primitivo int e você está passando um objeto Integer,
// neste caso, a JVM faz o auto unboxing de Integer para int
// mas o método remove é sobrecarregado,
// existe um remove que espera um tipo primitivo int
// e existe o remove que espera um objeto
// você está invocando o remove que espera o objeto a ser removido e não a posição a ser removida
listaRepetida2.get(posicao1).remove(posicao2);
listaRepetida2.get(posicao1).remove(posicao2);
Pois bem, evite escrever códigos como esse:
listaRepetida2.get(conta.get(i)).remove(conta.get(i + 1));
listaRepetida2.get(conta.get(i)).remove(conta.get(i + 1));
Com essas chamadas de métodos em cascata, você acaba se perdendo com o tipo de retorno e passagem de parâmetros. Reescreva o seu código que vai funcionar. Dica: Não chame o mesmo método mais de uma vez, guarde o resultado em uma variável local.
// mesmo que a lista contenha objetos Integer
// a JVM vai fazer o auto unboxing de Integer para int
// pois a variável é do tipo int
int posicao1 = conta.get(i);
int posicao2 = conta.get(i + 1);
listaRepetida2.get(posicao1).remove(posicao2);
listaRepetida2.get(posicao1).remove(posicao2);
Responder

Gostei + 0

22/10/2014

Carlos Rocha

Rapaz! Não é que eu tinha feito esse teste antes de você postar e deu certo. Segue a classe toda. Se houver jeito de melhorar, me dá dica? Estou achando que esse monte de loops (i,j,k,l) pode ser melhorado mas não estou conseguindo achar a lógica.
import java.util.ArrayList;

public class RemoveRepetidas
{
  ArrayList<ArrayList<Integer>> listaRepetida = new ArrayList<ArrayList<Integer>>();
  
  RemoveRepetidas (ArrayList<ArrayList<Integer>> _listaRepetida)
  {
    this.listaRepetida = _listaRepetida;	
  }
  
    	
  String removeRepetida()
  {      
		 //System.out.println(this.listaRepetida);
		 ArrayList<Integer> conta = new ArrayList<Integer>();		  
         ArrayList<ArrayList<Integer>> listaRepetida2 = listaRepetida;
	       
		   
		   for (int i = 0; i < listaRepetida2.size(); i++)
		   {				 
  		      for (int j = i+1; j < listaRepetida2.size(); j++)
		      {			  
         		   for (int k = 0; k < listaRepetida2.get(i).size(); k++)
		           {	
  		               for (int l = 0; l < listaRepetida2.get(j).size(); l++)
		               {		
				           if (
				                ( listaRepetida2.get(i).get(k) == listaRepetida2.get(j).get(l) && listaRepetida2.get(i).get(k+1) == listaRepetida2.get(j).get(l+1) ) ||
					            ( listaRepetida2.get(i).get(k+1) == listaRepetida2.get(j).get(l) && listaRepetida2.get(i).get(k) == listaRepetida2.get(j).get(l+1) )
					          )
					          {
								  conta.add(j);
								  conta.add(l);
								  conta.add(l+1);
					          } 
							  
				              l++;
			           }
					   
			           k++;
		           } 
			  }
	        }
			
		    for (int i = 0; i < conta.size(); i++)
			{			  
			  int a = conta.get(i+1);
			  int b = conta.get(i+2);
			  
			  listaRepetida2.get(conta.get(i)).remove(a);
			  listaRepetida2.get(conta.get(i)).remove(b);
			  
			  i+=2;
			}
			
		    String texto = "{";
			
		    for (int i = 0; i < listaRepetida2.size(); i++)
			{			  
               for (int j = 0; j < listaRepetida2.get(i).size(); j++)
			   {			  
                  texto += listaRepetida2.get(i).get(j) + "," + listaRepetida2.get(i).get(j+1) + ",";
			      j++;
			   }
			   texto+= ",";
			}
           texto += "}";
	       
		   texto = texto.replace(",,",",");
		   texto = texto.substring(0,(texto.length()-2)) + texto.substring(texto.length()-1) ;
		   
		   return texto;
  }
}
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar